IRC logs for #openttd on OFTC at 2025-12-30
⏴ go to previous day
00:23:35 *** WormnestAndroid has quit IRC (Read error: Connection reset by peer)
00:25:10 *** WormnestAndroid has joined #openttd
01:02:08 *** ChanServ sets mode: +v tokai
01:09:05 *** tokai|noir has quit IRC (Ping timeout: 480 seconds)
02:26:25 *** WormnestAndroid has quit IRC (Ping timeout: 480 seconds)
02:29:10 *** WormnestAndroid has joined #openttd
02:45:46 *** Wormnest has joined #openttd
03:09:10 *** Wormnest has quit IRC (Quit: Leaving)
04:45:34 <DorpsGek> - Update: Translations from eints (by translators)
07:09:22 *** WormnestAndroid has quit IRC (Remote host closed the connection)
07:09:24 *** WormnestAndroid has joined #openttd
07:22:57 <andythenorth> hmm nml *appears* to be setting the correct bits for triggers
07:23:53 <andythenorth> maybe vehicle trigger bit 0 only triggers when the vehicle is fully loaded?
07:41:00 <andythenorth> did something change with triggers?
07:42:27 <andythenorth> if it did, it changed before 20240311 nightly 😛
07:47:49 <andythenorth> hmm also the last vehicle appears to never trigger
07:52:09 <andythenorth> testing trigger bit 1 `TRIGGER_VEHICLE_SERVICE` to see if it's an error in my grf - but visiting depot triggers random bits reroll as expected
07:53:47 <andythenorth> ok I tried bit 3 `TRIGGER_VEHICLE_ANY_LOAD`
07:54:43 <andythenorth> all vehicles are syncing their choice except last
08:02:36 *** rito12_51026 has joined #openttd
08:03:54 <andythenorth> at first glance that's too recent 🙂
08:18:11 <andythenorth> `if (v->cargo.StoredCount() == 0) TriggerVehicleRandomisation(v, VehicleRandomTrigger::NewCargo);` entails that `NewCargo` (trigger bit 0) only triggers if the vehicle was empty?
08:59:05 <peter1138> > Vehicle gets new load of cargo (only after it was empty)
08:59:09 <peter1138> That is what it means, yes.
08:59:57 <peter1138> I assume you are missing the point of this?
09:32:57 <andythenorth> why do some triggers set all vehicle bits the same?
10:30:11 <andythenorth> ok so it's intended that all the bits are copied recursively along the chain?
10:31:09 <andythenorth> so trying to use this for randomising containers is basically, using it wrong
10:42:09 <andythenorth> my C++ reading is not good enough 😛
10:42:55 <andythenorth> are some cases setting the *same* random bits for every vehicle in the chain? Or the same indexd slice of bits, but reseeded?
10:47:10 <rito12_51026> You could try adding/multiplying the random bits by position in consist and then modulo by number of cases you have
10:48:19 <andythenorth> to debug what it's actually doing?
10:48:26 <andythenorth> probably better to read the src in that case
10:49:21 <rito12_51026> andythenorth: no, to get different data for each wagon
10:49:37 <xarick> I had an idea! a good night of sleep does wonders!
10:49:41 <andythenorth> it's random varact2, I can't pick the bits
10:49:53 <andythenorth> I'd have to multiply the result from the random varact2
10:51:14 <Borg> andythenorth: NFO or NML?
10:51:38 <Borg> I know. but what are you using NFO directly.. or NML?
10:51:54 <Borg> I dropped into middle of conversation. so no clue yet whats the problem. but if NFO.. I might help..
10:52:19 <andythenorth> hmm maybe I should read the nfo
10:52:48 <Borg> probably nobody is using NFO directly anymore [; everyone moved to NML
10:54:16 <andythenorth> `// Name: switch_spritelayer_cargos_intermodal_containers_low_floor_32px_random_tank_DFLT
10:54:16 <andythenorth> 25716 * 15 02 00 F2 80 04 \b0 04
10:54:16 <andythenorth> \wx00A3 // (1/4) -> (1/4): ss_spritelayer_cargos_intermodal_containers_low_floor_32px_tank_DFLT_0;
10:54:16 <andythenorth> \wx0094 // (1/4) -> (1/4): ss_spritelayer_cargos_intermodal_containers_low_floor_32px_tank_DFLT_1;
10:54:16 <andythenorth> \wx00AC // (1/4) -> (1/4): ss_spritelayer_cargos_intermodal_containers_low_floor_32px_tank_DFLT_2;
10:54:17 <andythenorth> \wx00F2 // (1/4) -> (1/4): ss_spritelayer_cargos_intermodal_containers_low_floor_32px_tank_DFLT_3;
10:54:19 <andythenorth> this looks correct
10:58:16 <andythenorth> yeah I think, as far as I can tell, nmlc is doing the right thing
11:00:29 <Borg> btw.. NMLC does bad job at formatting .nfo output.. 25716 * <size>\t\t<bytes> is a must
11:00:56 <andythenorth> it's random action 2
11:01:04 <rito12_51026> andythenorth: Why not sth like this?
11:01:04 <rito12_51026> random_switch (FEAT_TRAINS, SELF, switch_spritelayer_cargos_intermodal_containers_default_24px_random_box_DFLT, bitmask(TRIGGER_VEHICLE_ANY_LOAD)) {
11:01:04 <rito12_51026> 1: helper_switch(0);
11:01:04 <rito12_51026> 1: helper_switch(1);
11:01:06 <rito12_51026> 1: helper_switch(2);
11:01:06 <rito12_51026> 1: helper_switch(3);
11:01:07 <Borg> ahh the one I never used yet :D
11:01:08 <rito12_51026> 1: helper_switch(4);
11:01:08 <rito12_51026> 1: helper_switch(5);
11:01:10 <rito12_51026> 1: helper_switch(6);
11:01:10 <rito12_51026> 1: helper_switch(7);
11:01:12 <rito12_51026> 1: helper_switch(8);
11:01:12 <rito12_51026> 1: helper_switch(9);
11:01:14 <rito12_51026> 1: helper_switch(10);
11:01:14 <rito12_51026> 1: helper_switch(11);
11:01:16 <rito12_51026> 1: helper_switch(12);
11:01:16 <rito12_51026> 1: helper_switch(13);
11:01:18 <rito12_51026> 1: helper_switch(14);
11:01:18 <rito12_51026> 1: helper_switch(15);
11:01:20 <rito12_51026> Where helper_switch is a switch (not random_switch) with a parameter, in wich you do multiplication?
11:03:03 <Borg> andythenorth: I think its missing the byte?
11:04:10 <Borg> specs says 4xB: <count> <rnd-trig> <randbit> <nrand>
11:04:25 <Borg> 25716 * 15 02 00 F2 80 04 \b0 04 \wx00A3 \wx0094 \wx00AC \wx00F2
11:05:24 <andythenorth> `<Sprite-number> * <Length> 02 <feature> <set-id> 84 <count> <random-triggers> <randbit> <nrand> <set-ids>`
11:05:45 <Borg> yeah.. so one byte missing?
11:06:19 <andythenorth> I think that's only evaluated for 84
11:07:09 <andythenorth> I'm trying to understand the recursion of `case VehicleRandomTrigger::NewCargo:`
11:08:39 <Borg> group->triggers = GB(triggers, 0, 7);
11:08:39 <Borg> group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
11:08:39 <Borg> group->lowest_randbit = buf->ReadByte();
11:08:39 <Borg> group->num_groups = buf->ReadByte();
11:08:45 <Borg> seems all data is required
11:08:58 <Borg> 0x84 uses it... other ignore it
11:09:06 <Borg> so you must provide all data..
11:10:47 <Borg> fix by hand.. the .nfo file.. grfcoded it and test?
11:13:03 <andythenorth> can try, but the spec says `<Sprite-number> * <Length> 02 <feature> <set-id> [80|83] <random-triggers> <randbit> <nrand> <set-ids>`
11:14:29 *** gelignite has joined #openttd
11:14:49 <Borg> there is if: if (HasBit(type, 2)) {
11:15:15 <Borg> and count is read additionaly
11:15:20 <Borg> so indeed, it looks proper
11:15:35 <Borg> so specs is right and code is right...
11:17:02 <andythenorth> behaviour is weird
11:17:05 <Borg> now.. why it doesnt work [;
11:21:33 *** Flygon has quit IRC (Read error: Connection reset by peer)
11:21:45 <andythenorth> trigger `Vehicle gets new load of cargo (only after it was empty)` on bit 0 is called when vehicle completes loading
11:22:24 <andythenorth> and not when the vehicle begins loading
11:30:12 <Borg> andythenorth: bug in code? :D
11:30:33 <Borg> anyway.. that stuff worked before? or you trying sth new?
11:30:51 <andythenorth> I have been bisecting
11:30:58 <Borg> its strange that only NewCargo have v->First()
11:31:04 <Borg> all other cases uses v->Next()
11:31:12 <andythenorth> the behaviour is broken in older Horse, so it's not a change in the grf
11:31:31 <andythenorth> the behaviour is broken in OpenTTD nightly from March 2024
11:31:40 <andythenorth> I haven't bisected further
11:31:51 <Borg> DoTriggerVehicleRandomisation(v->First(), VehicleRandomTrigger::AnyNewCargo, new_random_bits, false);
11:32:01 <Borg> should be v->Next() here? [; but.. its kinda blind shot
11:34:37 <andythenorth> v->First() is correct I believe
11:35:25 <andythenorth> when we load new cargo we do want to then recurse that to the consist, from first vehicle
11:35:44 <Borg> im not sure.. its recursion already and it calls w/ first=false
11:35:56 <Borg> but.. I always had hard time analising OpenTTD code [;
11:38:39 <rito12_51026> andythenorth: Is it broken in v13.3 ?
11:39:39 <andythenorth> hard to test, Horse depends on newer grf features
11:54:58 *** __abigail has joined #openttd
11:55:44 <rito12_51026> but commit checker will fail
11:56:41 <rito12_51026> ah it failed already
12:02:50 <__abigail> rito12_51026: Yeah I am dumb and can't read
12:03:36 <andythenorth> ah callback 0x01
12:03:49 <andythenorth> `'random_trigger' : {'type': 'cb', 'num': 0x01}, # Almost undocumented, but really neccesary!`
12:12:46 <andythenorth> something in the Horse varact2 chain is causing unwanted behaviour when cb 0x01 triggers
12:13:22 <andythenorth> possibly trying to use registers, or accessing certain vars 🤷♂️
12:24:38 <peter1138> Effectively it's meant to be the graphics chain, not a separate route.
12:25:34 <xarick> I simplified further value_iter tracking. std::map now stores keys to std::set::iterators directly
12:25:53 <peter1138> "meant to be" as in, that's how NewGRFs should be written. No specific test for CB1, just going through the graphics chain, so that the random varactions in the graphics chain do the thing.
12:32:58 <andythenorth> nml has specific handling of cb 0x01, but I haven't read what that looks like in the nfo
12:33:50 <Borg> andythenorth: Callback 0x01 ?
12:34:07 <Borg> the very first callback I see is 0x10
12:37:05 <andythenorth> 'almost undocumented' may mean something
12:38:53 <Borg> CBID_RANDOM_TRIGGER = 0x01
12:51:26 <andythenorth> I just read the nml src 😛
12:51:54 <andythenorth> random triggers are now working for me, having changed my varact2 chain
12:52:09 *** ahyangyi has joined #openttd
12:52:14 <andythenorth> the cause is 'woo', as it's not obvious what causes the unexpected behaviour
12:52:44 <ahyangyi> How many hidden callbacks are there in the game?
12:53:08 <andythenorth> they're not hidden 😛
12:53:22 <ahyangyi> In the sense of open source, right?
12:53:40 <andythenorth> they're listed in newgrf_callbacks.h
12:55:17 <andythenorth> hmm, the upper and lower decks are supposed to be independently random ;P
12:55:26 <andythenorth> they're spritelayers
12:56:22 <ahyangyi> Looks pretty random to me
12:57:48 <andythenorth> upper and lower are same
12:57:59 <ahyangyi> Perhaps I should also make everything more randomized?
13:00:36 *** mmtunligit has joined #openttd
13:00:36 <mmtunligit> are you allowed to pass a vector to a function in command scope?
13:02:13 <mmtunligit> im trying to figure out why my thing wont build but its throwing such a long chain of errors i cant see where the problem actually is
13:02:25 <mmtunligit> it wont let me scroll back that far
13:05:56 <mmtunligit> definently has something to do with the endian buffer though based on what its complaining about
13:06:59 <peter1138> You can, but you'll need to implement serialisation for it.
13:07:29 <peter1138> Have a look at vehicle_cmd.h
13:07:48 <peter1138> That serialises an array, so there's not need for size information to be sent.
13:08:03 <peter1138> For a vector you'd want to send the number of items first, then each item.
13:42:25 <andythenorth> they're not random, but eh
13:42:34 <andythenorth> we don't have random bits per sprite layer 🙂
13:42:50 <andythenorth> and I can't be arsed to randomise an offset for one of the layers
13:43:22 <andythenorth> at least the car colours are not synced upper / lower decks now 🙂
14:01:10 <Borg> andythenorth: indian trains? [;
14:04:39 *** Flygon has quit IRC (Read error: Connection reset by peer)
14:14:24 <xarick> std::map<SQInteger, ScriptListSet::iterator>
14:15:46 <xarick> same memory usage as unmodified master
14:17:26 <xarick> instead of a map of [item, value], it's a map of item [item, value_iter]
14:24:04 <peter1138> Storing iterators is usually a bad idea.
14:25:58 <xarick> i could make this a bit slower if i get rid of a temporary vector I use for bulk insert
14:27:07 <_jgr_> Your own results suggest that it's not worth the bother
14:29:55 <xarick> there's only an advantage if no list copies or swaps are being made
14:31:56 <_glx_> your description of the issue was incomplete
14:33:36 <_glx_> as peter1138 said and your PR to fix an existing issues regarding iterators shows, storing iterators is a bad idea
14:34:12 <_glx_> it's a pain to make sure they are still valid
14:35:05 <_glx_> and it's very easy to forget an update
14:43:16 <_glx_> the biggest hit might be the `this->items.clear()`
14:43:24 <xarick> swap list would so this
14:44:33 <_glx_> because clear() complexity is linear to the size
14:45:43 <xarick> copy list would do this:
14:45:43 <xarick> ```void ScriptList::CopyList(const ScriptList *list)
14:45:43 <xarick> this->Sort(list->sorter_type, list->sort_ascending);
14:45:43 <xarick> this->values = list->values;
14:46:18 <xarick> iterators will be fine in this order, I tested
14:47:08 <xarick> I'm also assuming 14772 is in
14:47:57 <xarick> those Retargets need to be done after this->items already have the refreshed iterators to this->values
14:50:51 <xarick> gonna test the slower method, see if it's worth it
15:13:14 <xarick> oh lord, it's slow, for some unforeseen reason
15:13:36 <xarick> 512 seconds in RemoveItemTests :|
15:36:14 <_glx_> if it has copy assignment and/or clear() they are affected by size
15:56:01 <xarick> why is the buffer method so much faster.. i thought it was only a little faster, turns out it's like 5x faster
16:06:21 <xarick> wondering if std::array is even faster
16:09:03 <_jgr_> It's faster because you're sorting the items before inserting them into the map
16:09:46 <_jgr_> std::array is fixed size so not appropriate here, std::vector is effectively a variable size std::array already
16:20:54 *** WormnestAndroid has quit IRC (Remote host closed the connection)
16:20:55 *** WormnestAndroid has joined #openttd
16:23:38 *** gelignite has joined #openttd
16:25:03 <xarick> trying to think of alternatives methods to make this copy faster
16:26:22 <_glx_> if you want a faster copy, reduce the number of items
16:27:19 <xarick> actually, it's just the SwapList method now
16:27:57 <xarick> yes, with the original code
16:28:21 <_glx_> but with your stored iterator you need to update all nodes
16:29:51 <xarick> I feel I'm so close...
16:30:12 <xarick> it's just the SwapList now
16:30:21 <_glx_> anything that needs to iterate all items can't be fast
16:37:09 <andythenorth> does it really cost £50 to add some USB-C ports to a gaming PC? 😮
16:37:30 <andythenorth> (it has none on board, USB-C was too modern in 2023 when it was purchased)
16:37:37 <peter1138> How much does it cost to add them to a Mac?
16:40:48 <peter1138> Depending on how many you want, £20.
16:41:33 <andythenorth> infinite to add them to a mac
16:42:25 <andythenorth> ok I found one for £20
16:42:33 <andythenorth> how do I know it works?
16:42:43 <andythenorth> Amazon comments are variable, and the good ones are probably fake
16:43:02 <andythenorth> I haven't added a PCI card to anything for about 20 years
16:43:11 <andythenorth> it mostly used to just work?
16:46:49 <andythenorth> do PC motherboards not have a USB-C onboard internally?
16:47:10 <LordAro> they'll probably have a usb3 header
16:47:21 <LordAro> but it's probably being used for your front panel
16:48:08 <peter1138> Possibly some are unused. But you need to look at the manual, and look at what's connected.
16:48:28 <andythenorth> there is no front panel, but there is a top panel, USB A only
16:48:54 <andythenorth> the case has 7 PCI slots, but the motherboard only has 2 I think, and the GPU is in both
16:49:19 <peter1138> Yes, none of that tells you anyway. Look at the motherboard specs.
16:49:37 <andythenorth> can I not just look for ports on it?
16:49:45 <andythenorth> it does have 8 or 9 USB-A ports, most of which are USB 2, not 3
16:50:09 <andythenorth> he's got bored anyway, I'm going to ignore it again 😛
16:50:49 <andythenorth> think he just has it for some minecraft version where there's no mac build
16:53:49 <LordAro> unless he explicitly needs a fast connection, a basic usb splitter is probably fine
16:54:27 <andythenorth> it's a mic, keyboard, mouse
16:54:47 <LordAro> startech is usually fairly good
16:55:09 <LordAro> keyboard & mouse is nothing, mic isn't a lot more
16:55:19 <andythenorth> it kind of grates on me to be buying a USB-A hub when 2026 is here tomorrow 🙂
16:56:10 <LordAro> tomorrow? andy living in the future
16:56:30 <andythenorth> "somewhere on the globe"
16:58:03 <LordAro> eh, usb isn't going anywhere anytime soon
16:58:20 <Borg> andythenorth needs fat pipes.. because he is compiling his 25GB binaries [;
17:36:09 *** Wormnest has joined #openttd
18:04:32 *** MinchinWeb[m] has quit IRC (Ping timeout: 480 seconds)
18:05:06 *** MinchinWeb[m] has joined #openttd
18:08:15 *** gelignite has quit IRC (Read error: Connection reset by peer)
18:08:31 *** gelignite has joined #openttd
18:19:56 <xarick> I'm attempting some crazyness
18:21:06 <xarick> no idea where this will lead me to
18:21:21 <_zephyris> Minimum bridge height for a buoy?
18:21:32 <_zephyris> Probably not needed.
18:33:10 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
18:38:02 *** WormnestAndroid has quit IRC (Ping timeout: 480 seconds)
18:39:24 *** WormnestAndroid has joined #openttd
18:45:31 <xarick> oops, having trouble in the node_handle
19:03:21 <peter1138> _zephyris, there will be one already.
19:05:54 <peter1138> Gah, wrong functioN :D
19:22:14 *** gelignite has quit IRC (Read error: Connection reset by peer)
19:22:39 *** gelignite has joined #openttd
19:23:11 *** talltyler has joined #openttd
19:23:11 <talltyler> Did you see the `CmdBuildRoadWaypoint` at the top of the GitHub diff window too?
19:26:43 <peter1138> This is how I would do it.
19:28:42 <peter1138> Follows the existing pattern and uses the correct height. Which is 1, so it doesn't *really* matter but...
19:35:25 *** Flygon has quit IRC (Read error: Connection reset by peer)
19:54:26 <xarick> omg, i can't believe the abomination I just did works
19:56:55 <xarick> reduces the size of ScriptList by 8 bytes per item over master
20:00:54 *** gelignite has quit IRC (Read error: Connection reset by peer)
20:02:22 *** gelignite has joined #openttd
20:02:27 <xarick> i stumbled in the node_handle though
20:08:45 *** MinchinWeb[m] has quit IRC (Read error: Connection reset by peer)
20:09:01 *** MinchinWeb[m] has joined #openttd
20:13:24 <xarick> ```assert(*item_iter != this->values.end());
20:13:24 <xarick> auto node_handle = this->values.extract(*item_iter);
20:13:24 <xarick> node_handle.value().first = value;
20:13:24 <xarick> this->items.erase(item_iter);
20:13:24 <xarick> this->items.emplace(this->values.insert(std::move(node_handle)).position);```
20:16:16 <_glx_> of course it fails, `value` is not a pair
20:25:03 <_glx_> anyway you're hitting the wrong nail
20:25:53 <_glx_> and just make things harder to use
20:26:35 <andythenorth> would it all go faster on a modern CPU?
20:26:49 <andythenorth> when I run out of optimisations on Horse, I buy a new laptop
20:28:14 <xarick> sub_range doesn't like what i'm doing
20:30:33 <_glx_> it may not like you reordering the data inside the range
20:33:05 <_glx_> and if you erase the current item, you most likely kill the iterator used by Valuate
20:33:32 <xarick> oh, it is failing to that
20:33:48 <_glx_> "References and iterators to the erased elements are invalidated."
20:34:39 <xarick> will the next_iter save this?
20:35:44 <_glx_> when using iterators you have to be very careful
20:36:01 <andythenorth> wonder if there's a way to shim in a `Consist` class without having to replace every `Vehicle *v` accessor or similar
20:36:02 <_glx_> the footgun is as big as the pointer one
20:41:16 *** michi_cc[d] has joined #openttd
20:42:11 <andythenorth> most of my 2025 grf stuff was removing every reference to "consist" in Horse
20:42:37 <andythenorth> as it was used as the name for a wrapper around multi-part articulated vehicles or single-part vehicles
20:42:39 <_glx_> someone with bad luck in timing
20:50:10 *** WormnestAndroid has quit IRC (Read error: Connection reset by peer)
20:51:28 *** WormnestAndroid has joined #openttd
20:55:06 *** Wormnest has joined #openttd
21:05:01 *** Borg has quit IRC (Quit: leaving)
21:46:00 *** MinchinWeb[m] has quit IRC (Read error: Connection reset by peer)
21:46:12 *** MinchinWeb[m] has joined #openttd
21:53:35 <xarick> regression doesn't crash, but it's not passing
21:55:09 <xarick> I suspect a PostErase is required
22:05:06 <xarick> found the problem :) ->first should be ->second in one of the places
22:06:15 <xarick> very easy to get this wrong now :P
22:06:32 *** MinchinWeb[m] has quit IRC (Ping timeout: 480 seconds)
22:07:03 *** MinchinWeb[m] has joined #openttd
22:07:14 <xarick> success!! regression passes
22:09:27 <xarick> was also able to use node_handle
22:15:07 *** MinchinWeb[m] has quit IRC (Ping timeout: 480 seconds)
22:15:07 *** MinchinWeb[m] has joined #openttd
22:29:52 <xarick> disapointing 518 seconds :|
22:46:23 *** Wolf01 has quit IRC (Quit: Once again the world is quick to bury me.)
22:46:52 *** MinchinWeb[m] has quit IRC (Ping timeout: 480 seconds)
22:47:40 *** MinchinWeb[m] has joined #openttd
22:51:45 <xarick> is it pointer chasing?
23:20:08 <_glx_> as I said earlier, when you need to iterate the full list to update your iterators you're slowing everything
23:21:40 <_glx_> there's always a balance between memory usage and cpu usage
23:21:55 *** MinchinWeb[m] has quit IRC (Ping timeout: 480 seconds)
23:22:55 *** MinchinWeb[m] has joined #openttd
23:23:40 <_glx_> less memory used, but now you need more cpu to keep the data up to date
23:29:50 <xarick> in that case, this is the best I can do
23:30:17 <xarick> this uses a std::map<SQInteger, ScriptListSet::iterator>
23:30:37 <xarick> same memory usage as master, except when doing list copying
continue to next day ⏵