IRC logs for #openttd on OFTC at 2023-02-04
β΄ go to previous day
00:00:23 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
00:24:57 *** HerzogDeXtEr has quit IRC (Read error: Connection reset by peer)
00:25:46 *** WormnestAndroid has quit IRC (Read error: Connection reset by peer)
00:25:55 *** WormnestAndroid has joined #openttd
00:38:32 *** Wormnest has joined #openttd
01:31:15 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
01:42:28 *** Etua has quit IRC (Ping timeout: 480 seconds)
01:51:22 *** Wormnest has joined #openttd
02:00:23 *** Wormnest has quit IRC (Quit: Leaving)
03:47:31 *** D-HUND has quit IRC (Ping timeout: 480 seconds)
05:55:56 *** Beer has quit IRC (Quit: Leaving)
06:43:55 *** esselfe has quit IRC (Ping timeout: 480 seconds)
07:03:01 *** esselfe has joined #openttd
08:36:06 <andythenorth[d]> ok so how about a GS batch command system that uses 2 ticks
08:36:34 <andythenorth[d]> 1st tick: push a list of instances over which to map a command (all of one type: town, industry, tile etc)
08:36:51 <andythenorth[d]> 2nd tick: push the command
08:37:09 <andythenorth[d]> there would need to be a parameter for whether to abort on errors or not
08:37:14 <andythenorth[d]> and some return value
09:19:24 *** sla_ro|master has joined #openttd
09:49:56 *** HerzogDeXtEr has joined #openttd
10:18:46 <TrueBrain> okay, sentry-native to capture crashes works pretty good honestly
10:19:07 <TrueBrain> it just doesn't allow our own handler to work; but I guess that kinda makes sense π
10:21:10 <TrueBrain> for Linux, it uploads the crash on the next time you start OpenTTD
10:30:16 <TrueBrain> owh, for most crashes, we have an `on_crash` callback, where we can present the user with information; so we are not completely lost on that front .. interesting π
10:48:09 <TrueBrain> ha, I can daisy-chain Sentry's crash handler and ours now π At least for Linux π
10:48:31 <TrueBrain> how can I test this for Windows .. hmmm
11:00:08 <andythenorth[d]> βIn the cloudβ
11:03:31 <TrueBrain> guess I need to install MSVC? Meh π
11:05:49 <TrueBrain> you got to love downloading with 70 MB/s .. lol and that is even slow π
11:07:07 <michi_cc[d]> Public service announcement: "Slack" time is over, if you want something in 13.0 proper, make a PR today. Tag tomorrow one way or the other.
11:07:36 <TrueBrain> Totally unfinished, as it needs to ask for consent, and fill in a lot more details towards Sentry .. but you get the idea. Very little code required π
11:15:31 * andythenorth[d] such GS designing
11:16:16 <andythenorth[d]> can do most of a FIRS GS, only 1 or 2 features lacking π
11:19:44 <TrueBrain> shocking, MSVC "just works" .. the COMPILING.md is pretty good π
11:20:39 <TrueBrain> okay, I spoke too soon π vcpkg integration wasn't picked up, so no zlib support, so bootstrap crashes π
11:20:44 <TrueBrain> (as it cannot extract the package)
11:22:46 <michi_cc[d]> BTW, a debug build already has an Alt + 0 hotkey (it is even called GHK_CRASH and can be remapped π )
11:23:00 <TrueBrain> ah, I installed `x64-windows-static`, but it looks for `x64-windows` .. that is an easy fix π
11:23:27 <TrueBrain> michi_cc[d]: yeah, I know, but for some reason it wasn't working when I was looking for it π Went for the easier solution π
11:26:00 <TrueBrain> yeah, doesn't work in WSLg at least
11:33:24 <andythenorth[d]> story page buttons then
11:33:35 <andythenorth[d]> On towns and industries
11:34:01 <andythenorth[d]> Text, or an unlabelled story page icon?
11:34:06 <TrueBrain> lol, `small` is no longer a valid variable name for my MSVC build now
11:35:22 <TrueBrain> nothing an `#undef small` doesnt fix, but that is just weird π
11:40:30 <TrueBrain> okay, for Windows, it starts a second executable `crashpad_handler`. From what I read, that is also how things like Chrome work .. just can't find evidence of that actually happening π
11:40:46 <glx[d]> It's a integer type IIRC
11:41:27 <TrueBrain> but otherwise, also Windows "just works" π
11:41:40 <TrueBrain> now I wonder if I can still trigger our own crash-log handler ..
11:43:18 <andythenorth[d]> Gui buttons are some kind of widget
11:43:48 <andythenorth[d]> Channel is today βinside of peopleβs brainsβ
11:44:57 <glx[d]> Samu: I think an option would be to use __1 for -1 with the correct handling
11:50:10 <andythenorth[d]> What should story pages be allowed to attach to?
11:50:18 <andythenorth[d]> Towns, industries
11:53:20 <TrueBrain> glx[d]: : is there a way to keep the debug console open after OpenTTD closes? By starting it in some way from a powershell or something?
11:54:39 <glx[d]> And it's som see times annoying
11:54:52 <andythenorth[d]> Story page for a tile? π€ͺ
11:55:30 <TrueBrain> either way, I can also show the old crashlog window, w00p
11:55:36 <Samu> i need a customized atoi to treat '_' as '-'
11:55:42 <TrueBrain> just don't need the `esp` trick to make that happen
11:55:47 <TrueBrain> in fact .. that really doesn't work π
11:56:14 <glx[d]> No samu, you need to check if there are 2 _ and do some handling
11:56:57 <glx[d]> `int key = atoi(key_string + 1);`
11:58:01 <glx[d]> Remove the first char of key_string, test if new first char is _ and improvise before calling atoi
12:04:31 <andythenorth[d]> Story page for bouys?
12:08:22 <TrueBrain> okay, so showing the crashlog window on Windows is rather tricky. But not the most important thing I guess
12:08:51 <TrueBrain> we would need to change some `ExitProcess` into `EndDialog`, and it should be fine π
12:09:46 <TrueBrain> the other tricky part is to embed `crashpad_handler.exe` into the main executable, as otherwise you will get reports "what is this crashpad handler?!", especially as someone very bright (sarcasm) claims on the internet it is a coin miner (it isn't :P)
12:10:23 <TrueBrain> other than that, I think this is viable. That brings us to the question: do we want this? π
12:11:40 <TrueBrain> Some impressions how the collected data looks π
12:16:36 <michi_cc[d]> Could you use the crash dialog to ask for the upload permission (i.e. some "send to developers" button), or is this already too late into the crash process?
12:17:30 <andythenorth[d]> TrueBrain: but I never said it was a coin miner π
12:21:46 <TrueBrain> michi_cc[d]: For Windows we can, yes
12:22:08 <TrueBrain> For Linux we have no dialog
12:22:44 <TrueBrain> No clue if that could be added π
12:23:04 <TrueBrain> MacOS in general is a bit more tricky, as it handles crashes in a weird way
12:24:20 <Samu> there should be a way to enforce the limitation here
12:25:09 <Samu> clamping on a label feels wrong, it should not compile instead, unless there's a better solution
12:26:53 *** sla_ro|master has quit IRC ()
12:26:59 <michi_cc[d]> For MacOS, I think that as we now sign OpenTTD, we could somehow get the crash reports from the Apple developer account, but I have no idea if something can be automated there. I could also be wrong here, never bothered to really find out.
12:27:47 <TrueBrain> Sentry-native and crashpad docs are full of "for MacOS ..." indicating things are limited
12:28:08 <TrueBrain> For example, `on_crash` callback is not called
12:28:40 <TrueBrain> But okay, MacOS doesn't have the most users, so I am fine if that still uses the old flow
12:28:58 <TrueBrain> Windows is the important target here π
12:33:46 <andythenorth[d]> Storybook for lighthouses?
12:34:03 <andythenorth[d]> βThe lighthouse keeper is hungryβ
12:43:12 <andythenorth[d]> βThe lighthouse keeper has caught a fishβ
12:47:57 <TrueBrain> I asked Sentry some questions how to deal with some aspects of their SDK. Mostly, we have to upload symbols for every release. This is fine by me, but it is ~1GB per release
12:48:10 <TrueBrain> So I wonder if that is okay :p
12:48:46 <Eddi|zuHause> does that include nightlies?
13:11:22 <Samu> does atoi already clamps values?
13:23:05 <Samu> bing tells me to use strtol
13:37:30 <petern> You can use the C++ equivalents which 'helpfully' throw an exception instead...
13:42:58 <andythenorth[d]> what will the story page icon look like?
13:43:16 <andythenorth[d]> and will it go at the top right, or next to 'display chain' (which also opens another window)
13:58:16 <Eddi|zuHause> "requires oxygen" sounds like you're operating in deep space
14:00:28 <TrueBrain> awh, Win arm64 is not supported by sentry-native
14:01:54 <andythenorth[d]> story page icons
14:02:05 <andythenorth[d]> not sure which location is better
14:02:11 <andythenorth[d]> I think lower right?
14:03:10 <andythenorth[d]> with a red dot if there are updates? π
14:05:26 <glx[d]> makes more sense to me that way
14:16:56 <Samu> there's more type* var in game_gui.cpp yet
14:19:52 <glx[d]> haha "fast", I did that last night π
14:20:06 <Samu> when it was copy pasted, the editor applied it's own coding style
14:21:24 *** Flygon_ has joined #openttd
14:29:03 *** Flygon has quit IRC (Ping timeout: 480 seconds)
14:38:52 *** WormnestAndroid has quit IRC (Remote host closed the connection)
14:49:04 <Samu> dont know what to write in the documentation without becoming too complex
15:15:44 *** sla_ro|master has joined #openttd
15:16:24 <TallTyler> I'm disappointed that our AI revolution doesn't include quite as much robot personality as in popular media. CodeQL frantically raising warnings about our use of switches in GUI code would be more interesting if it had the personality of C-3PO and we could dismiss its alerts verbally in our best Han Solo impressions
15:20:56 *** WormnestAndroid has joined #openttd
15:21:19 <glx[d]> CodeQL is right, I closed 4 alerts and opened 5 new ones (4 being the closed ones because I moved code around)
15:21:45 <glx[d]> and I can trivially fix 4 of them
15:27:48 <glx[d]> now there should be 4 closed, 1 new
15:28:10 <andythenorth[d]> hmm can I declare classes in GS
15:29:47 <andythenorth[d]> "Classes are associative containers implemented as pairs of key/value. Classes are created through a 'class expression' or a 'class statement'. class members can be inherited from another class object at creation time. After creation members can be added until a instance of the class is created."
15:29:57 <andythenorth[d]> docs suggest a class is just a table
15:30:06 <andythenorth[d]> maybe I can put methods in table slots?
15:30:09 <glx[d]> everything is a table in GS
15:31:09 <andythenorth[d]> /me still testing whether to write actual GS, or whether to just do it all in python
15:31:56 <andythenorth[d]> so `function MainClass::Init()` is declaring the function, scoped to MainClass?
15:34:18 <andythenorth[d]> :: seems to be slot access
15:38:27 <andythenorth[d]> hmm that says `::` is for accessing global variables
15:39:10 <andythenorth[d]> lol every time I start GS my enthusiasm is destroyed π
15:39:20 <andythenorth[d]> nfo is easier and better documented afaict
15:40:13 <andythenorth[d]> although nfo isn't trying to be a high-level language either, so not a level playing field π
15:43:01 <andythenorth[d]> sadly no python -> squirrel transpiler exists
15:44:38 <andythenorth[d]> hmm what is AssemblyScript
15:44:42 <TallTyler> Okay, hoping I'm about done overloading actions for a while π
15:48:03 <TallTyler> Renaming english.txt strings to forcibly retire outdated translations was getting ugly, so I reset the repo to an old commit (detaching my head several times in the process until I figured out the right procedure). I think a better approach is deleting outdated strings from each translation, so if anybody has the script for that...now would be the time before I write a new Python script. π
15:49:36 <TallTyler> `# never leave empty strings or strings with only spaces in this list, that will strip everything from a lang file`?
15:49:40 <andythenorth[d]> it will delete the contents of all lang files if you give it an empty list or string
15:50:08 <TallTyler> Not that dangerous as long as you're not blindly committing things π
15:50:18 <andythenorth[d]> well I learnt the hard way π
15:50:31 <TallTyler> Thank you for the script, and the warning π
15:50:40 <TallTyler> That will save me several hours
15:51:30 <frosch> if you delete translations, eints will just readd them
15:52:34 <andythenorth[d]> I don't understand Squirrel namespaces (maybe there aren't any?)
15:52:34 <andythenorth[d]> Presumably I can't extend GSTown with my own methods, in Squirrel?
15:52:51 <andythenorth[d]> putting all the functions into root seems very 1994
15:53:18 <frosch> you can extend GSTown. just assign new members like in python
15:53:42 <TallTyler> frosch: Hmm, how do we escape that? Renaming 100+ strings to trick eints into thinking it's a new string is...ugly
15:53:43 <frosch> the compatibility scripts do just that
15:54:43 <frosch> TallTyler: why are your strings outdated?
15:55:40 <TallTyler> Changing the game to use real-world time units is disruptive π
15:56:27 <andythenorth[d]> frosch: thanks π
15:56:35 <andythenorth[d]> `function GSTown::Cabbage()
15:56:35 <andythenorth[d]> Log.Info("Cabbage");
15:56:46 <andythenorth[d]> not sure if I should extend GSTown
15:56:55 <TallTyler> english.txt changes are +100 -93
15:57:08 <andythenorth[d]> I don't grok the best way to use 'everything is a table' yet
15:57:17 <andythenorth[d]> maybe I need a class FIRSTown
15:57:37 <glx[d]> it's local to your script anyway andythenorth[d] so you can extend as you want without affecting any other script
15:57:39 <andythenorth[d]> but I don't want to instance one for every town, that's memory bloat
15:57:49 <andythenorth[d]> and I don't want a singleton, because singletons are bad
15:57:52 <andythenorth[d]> kind of weird
15:58:28 <andythenorth[d]> I want towns to be self-contained and take care of themselves
15:58:42 <andythenorth[d]> and I want to stop having to make lots of references and pass them around
16:00:46 <TallTyler> TallTyler: These are correct as long as calendar progress speed is 100%, but it's even more of a problem for strings where the unit has actually changed, for instance days to seconds
16:01:17 <andythenorth[d]> `towns.set_monthly_growth_rate()`
16:01:17 <andythenorth[d]> `foreach (town, _ in town_list) {
16:01:17 <andythenorth[d]> GSTown.SetGrowthRate(town, 1);
16:02:40 <andythenorth[d]> hmm but if I map the towns into a table, the game might found a new one meanwhile
16:03:04 <glx[d]> valuate is your friend here
16:03:06 <andythenorth[d]> how expensive are creating these lists?
16:03:24 <andythenorth[d]> e.g. GSTownList() etc
16:03:53 <andythenorth[d]> I am concerned that a lot of them are needed
16:04:14 <glx[d]> I think valuate can be abused
16:04:14 <andythenorth[d]> if they aren't created new for each function call, they might be stale respecting game state
16:04:29 <andythenorth[d]> but creating a lot of them seems horrifically inefficient
16:05:24 <glx[d]> a list is created each time you call GSTownList()
16:06:03 <andythenorth[d]> hmm actually this is more complex
16:06:13 <glx[d]> but you can create it in start, and update it following events
16:06:18 <andythenorth[d]> the map might have changed meanwhile, as the loop runs
16:06:31 <andythenorth[d]> so the town list / industry list / tile list etc might be out of date
16:07:15 <andythenorth[d]> this breaks my brain slightly
16:07:24 <andythenorth[d]> how to iterate over state that is changing meanwhile
16:07:27 <glx[d]> towns can't be removed, but you receive an event when a new one is founded
16:07:43 <andythenorth[d]> the event won't be processed while the loop is running though...
16:08:16 <andythenorth[d]> some of Zuu's code contains defenses against e.g. 'industry has been removed so is now invalid in the loop'
16:08:53 <glx[d]> yes for industries you need to be careful in the loop, but for towns the only risk is missing new towns
16:09:11 <glx[d]> and you can handle that via the event
16:09:24 <TallTyler> eints documentation lists my deleting old strings strategy under `I want to fight a bot and lose.` π
16:09:26 <glx[d]> add the town, apply what the loop was doing
16:10:14 <andythenorth[d]> inside each loop cycle, I could maybe compare the list being looped over against a new version of the list from the map
16:10:32 <andythenorth[d]> then abort the loop if the membership has changed
16:10:35 <TallTyler> Guess it's time to get renaming
16:10:37 <andythenorth[d]> and undo all the changes
16:11:34 <glx[d]> I think you can check events in the loop
16:11:35 <andythenorth[d]> oof this is like programming Flash apps where logic ran on the client, but part of the state was a multi-user experience on the server
16:11:47 <andythenorth[d]> I only did that once or twice, then never again
16:12:02 <andythenorth[d]> or like javascript, where state is just kept in the DOM, then something else changes it
16:12:50 <andythenorth[d]> ok so some kind of library is needed
16:13:00 <andythenorth[d]> can't really just rely on looping over GSList
16:14:03 <andythenorth[d]> maybe superlib has SafeLoop or something
16:15:01 <glx[d]> a possible solution is get the list on script start, valuate it with "false", then you can valuate again with a function checking the value, if false do_suff and return true
16:15:33 *** Wormnest has joined #openttd
16:15:42 <glx[d]> then when the new town event happens you add the town to the list with "false" and reapply the valuation
16:16:09 <andythenorth[d]> sounds almost like I could just keep my own list in a table
16:16:17 <andythenorth[d]> then manage add / remove manually with events
16:16:24 <andythenorth[d]> then do book-keeping
16:18:07 <andythenorth[d]> this would be easier if GS wasn't so slow π
16:18:45 <andythenorth[d]> actually I might want my own list anyway, then I can check if a town is up to date
16:18:48 <andythenorth[d]> or badly lagging
16:18:48 <glx[d]> foreach on a list is usually best replaced with valuate
16:19:10 <andythenorth[d]> can valuate take a command as the arg for valuating?
16:19:28 <glx[d]> you can pass it any function
16:21:22 <glx[d]> it returns a silly value, but I don't think anything prevent MyVal from doing stuff except using commands
16:21:23 <andythenorth[d]> walking the entire map is slow at saveload
16:21:41 <andythenorth[d]> currently I have to pause the game to run the script
16:22:04 <glx[d]> you're not supposed to walk the map at saveload
16:22:38 <glx[d]> ho no you mean it's slowing down when saving
16:22:56 <andythenorth[d]> this is for reloading the game
16:23:06 <andythenorth[d]> to reinit the GS on my test savegame
16:23:39 <andythenorth[d]> can't store any GS state in savegame, as it might be bad due to changes in dev
16:24:04 <andythenorth[d]> so the script has to run effectively stateless on load, and rebuild all the needed state
16:24:44 <andythenorth[d]> I might make a story page button that destroys all the state and calls init though
16:24:54 <glx[d]> I think your script might store too much state in its memory
16:25:14 <andythenorth[d]> I think we have up to 1 GB?
16:25:44 <andythenorth[d]> I wonder what the story page button does if its handler is destroyed while running
16:26:46 <andythenorth[d]> I did do a little test on RAM use, so far it only seems to increase OpenTTD RAM by 50% on my system
16:27:22 <andythenorth[d]> unscientific test
16:27:40 <glx[d]> maybe you store stuff in your GS that's not really needed
16:28:30 <andythenorth[d]> well I'm implementing areas in it
16:28:32 <andythenorth[d]> as lists of tiles
16:28:58 <andythenorth[d]> it might be fast enough to do those at run time without caching them
16:29:07 <andythenorth[d]> but walking the map takes 5s each time, so I doubt it
16:29:42 <glx[d]> can't the area of a tile be determined via math ?
16:29:54 <andythenorth[d]> yes possibly it can
16:30:13 <glx[d]> using f(x, y) might be more efficient
16:30:13 <andythenorth[d]> I can't quite see how yet, but it seems like a solution
16:30:43 <andythenorth[d]> the challenge is that the only way I can see to find town tiles is to walk all tiles and see which town they belong to
16:31:06 <andythenorth[d]> even though in most cases most tiles will obviously not belong to the town in scope for the check
16:31:17 <andythenorth[d]> it's quite a wasteful method
16:31:58 <glx[d]> yes there's no method for that in openttd, even highlight is done that way for some of them
16:32:19 <andythenorth[d]> town for a tile seems like it could have been indexed?
16:32:27 <andythenorth[d]> it only changes if town is founded or destroyed?
16:32:49 <andythenorth[d]> is it just too many bytes?
16:33:21 <glx[d]> usually distance to town is simpler to use
16:33:58 <andythenorth[d]> does that have the identical result?
16:34:12 <andythenorth[d]> a tile will always belong to nearest town?
16:36:11 <glx[d]> we have CalcClosestTownFromTile
16:37:33 <andythenorth[d]> hoping that's what industry uses to determine town
16:38:01 <andythenorth[d]> industry must have something different
16:38:05 <andythenorth[d]> not using CalcClosestTownFromTile
16:38:54 <andythenorth[d]> FindTownForIndustry
16:39:05 <andythenorth[d]> and then ClosestTownFromTile
16:40:31 <glx[d]> indirectly using CalcClosestTownFromTile
16:40:34 <andythenorth[d]> hmm seems script GetTownAuthority is using ClosestTownFromTile
16:41:22 <andythenorth[d]> that's puzzling
16:42:42 <glx[d]> there's also GetClosestTown
16:43:01 <glx[d]> the difference between the two is the threshold
17:02:08 * andythenorth[d] reading what this does
17:02:09 <andythenorth[d]> `_settings_game.economy.dist_local_authority`
17:02:59 <andythenorth[d]> oh local authority size is a setting?
17:03:46 <andythenorth[d]> ok so I can rely on GetClosestTown() to do the same thing as when an industry is constructed?
17:08:48 <andythenorth[d]> is there any way I can make prospecting deterministic?
17:09:22 <andythenorth[d]> I want to run it in test mode, check if the selected tile belongs to the correct town, then run it in do mode if so
17:21:20 <andythenorth[d]> hmm maybe I just copy the prospecting parts of CmdBuildIndustry into GS
17:21:22 <frosch> maybe add an api method that gives you 20 random locations suitable for an industry type, then the gs can pick one of them which it likes most
17:21:36 <andythenorth[d]> that sounds like areas TBH π
17:21:40 <andythenorth[d]> which isn't a thing right now
17:22:09 <frosch> well, right now it's all random
17:22:26 <frosch> you can do the same, pick a random tile, decide whether it fits your need, and then try build an industry
17:22:41 <andythenorth[d]> yeah that's what I'm considering
17:23:00 <andythenorth[d]> what is this for in CmdBuildIndustry? `Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);`
17:26:45 <frosch> it uses town rules for clearing tiles. it does not bulldoze player's infrastructure to make room for an industry π
17:27:16 <frosch> otherwise industries would spawn on purchased land
17:31:36 <frosch> hmm, i never tried asking gpt about specific lines of code... it proably can't read github links
17:33:41 <andythenorth[d]> it's not allowed the internet
17:34:57 <andythenorth[d]> hmm wonder if I can just loop through all tiles of a town
17:35:06 <andythenorth[d]> no, it might be a huge map with one town on it
17:42:59 <andythenorth[d]> if GS could stuff a grf register when running a cmd
17:43:14 <andythenorth[d]> then FIRS could read the town index from that register
17:43:40 <andythenorth[d]> and use it in CB 28
17:45:01 <frosch> i would try to make it less try-hard. don't loop all tiles of a town. instead pick tiles at random, and check whether they are close enough to the town
17:45:30 <frosch> looping all tiles would ask how to sort/shuffle the tiles, so towns would fill up with industries in some pattern
17:45:31 <andythenorth[d]> does that have a vanishingly low chance of success on a large map?
17:46:01 <andythenorth[d]> I was looking for a way to narrow the list to tiles for a town, then choose random
17:46:34 <frosch> what has map size to do with it? trying tiles at random has as good a success chance as trying them in order
17:46:45 <frosch> except you save the time/space to assemble the list
17:47:39 <frosch> if you have any way for narrowing down the tiles, i.e. some kind of pre-check, you can do the same check with a random tile, can't you?
17:49:37 <andythenorth[d]> maybe I misunderstand π
17:50:32 <andythenorth[d]> probability is always unintuitive π
17:52:02 <andythenorth[d]> picking a tile randomly from the whole map, with a constraint
17:52:17 <andythenorth[d]> is still faster than applying the constraint to the whole map, then picking a random one from the subset?
17:52:31 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
17:52:49 <andythenorth[d]> as long as I discard the tile from the list before picking the next random one
17:55:06 <petern> Hmm, Doom music is nice with this synth.
17:55:50 *** WormnestAndroid has quit IRC (Ping timeout: 480 seconds)
17:57:48 <andythenorth[d]> ddang ddang ddang
18:03:28 <frosch> andythenorth[d]: you use monte carlo method, if you have no better method π
18:03:49 <frosch> the strength of monte carlo method is, that it always works
18:04:04 <frosch> its weekness is that it is always worse than an actual good method :p
18:06:56 <andythenorth[d]> ok so I actually need n locations, where n = num towns / 2
18:07:18 <andythenorth[d]> so I could pick map tiles at random, and if they're in a town that doesn't have a location yet
18:07:27 <andythenorth[d]> which is slightly more efficient
18:08:30 <andythenorth[d]> no, I need more than n / 2 tiles, because they might not be valid industry locations
18:08:47 <andythenorth[d]> sometimes I wonder how I tie my own shoelaces
18:12:11 *** tokai|noir has joined #openttd
18:12:11 *** ChanServ sets mode: +v tokai|noir
18:18:41 *** tokai has quit IRC (Ping timeout: 480 seconds)
18:18:42 *** Wormnest has joined #openttd
18:19:55 <andythenorth[d]> ha 'php' is the best match for GS syntax highlighting in my editor π
18:20:06 <andythenorth[d]> I expected C++ would be
18:27:08 <andythenorth[d]> oh prospecting is deterministic π
18:27:12 <andythenorth[d]> things I forget
18:27:50 <andythenorth[d]> my GS prospects farms, everytime I reload the savegame they're built afresh in the same places
18:38:05 <Samu> GetClosestTown used to be expensive before kdtree, not sure how it is now, but I suppose it's easier on the cpu
18:42:02 <Samu> #10385 is too difficult for me...
18:42:55 <TallTyler> All renamed and pushed, let's see if it builds π€
18:43:22 <TallTyler> Er, passes CI I mean
18:44:20 <DorpsGek> - Update: Translations from eints (by translators)
18:45:44 <Samu> seems to be layout_cache having deleted data, invalid then, so, a non-validated cache, but I have no idea how to fix this
18:47:42 <andythenorth[d]> function names in Squirrel need to be lower case or camel case?
18:47:49 <andythenorth[d]> squirrel 2 docs use both interchangeably
18:48:05 <andythenorth[d]> also table slots should be named as lower case, or upper?
18:48:14 <andythenorth[d]> again squirrel docs seem to do both
18:53:02 <andythenorth[d]> I don't want to choose
18:56:57 <TallTyler> * uses admin powers to delete the bot post proving I didn't get it on the first try π
18:57:39 <andythenorth[d]> ok so GS functions are camel case
18:58:16 <andythenorth[d]> this is going to be ugly
18:58:49 <andythenorth[d]> all the nml and python tokens are lower case, except global constants
18:59:05 <andythenorth[d]> I'm going to have to string parse them appropriately by type into the GS
18:59:46 <andythenorth[d]> and then switch my brain around every time I move from python to squirrel
19:01:51 <andythenorth[d]> `scrap_yard` in python becomes `FIRS.GetScrapYard`
19:02:20 <andythenorth[d]> or maybe `FIRS.GetIndustry(SCRAP_YARD)`
19:10:56 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
19:14:22 <andythenorth[d]> it's not an assignment, so why call the function?
19:14:34 <andythenorth[d]> and the parameter isn't in scope, so the function call will fail
19:15:07 <andythenorth[d]> and a function isn't called by declaring it anyway
19:15:45 <andythenorth[d]> it's not the definition of the function, that's on L54
19:25:43 *** Flygon_ has quit IRC (Read error: Connection reset by peer)
19:27:49 <michi_cc[d]> I would assume it is a function prototype. No idea if you actually need it or not.
19:31:01 <andythenorth[d]> kind of confused in Squirrel, if everything is a table slot
19:31:05 <andythenorth[d]> why have classes?
19:31:22 <andythenorth[d]> oh so they can be instanced maybe
19:31:26 <michi_cc[d]> You could ask that JavaScript, too.
19:31:39 <andythenorth[d]> TBH I try to never touch javascript
19:31:47 <andythenorth[d]> I've done it for money and it's horrific
19:32:04 <andythenorth[d]> I wrote tens of flash games without any classes
19:32:11 <andythenorth[d]> everything just functions
19:33:08 <andythenorth[d]> oof it's not that I love python, but it's just really really obvious in python what you should do and why
19:33:10 <Samu> issue #10311, is that in consideration?
19:33:26 <andythenorth[d]> and I can read most of our C++ even if I can't write it, and when it's explained, it makes total sense
19:33:37 <andythenorth[d]> some of the other higher level languages...just seem WTF
19:33:57 <Samu> i had pr'ed such setting before, was rejected entirely
19:34:14 <Samu> now it gets a "good first issue"
19:35:12 <Samu> something along the lines of "make a newgrf" was the excuse
19:40:48 <Samu> yeh i rememberd correctly
19:42:25 <andythenorth[d]> Samu there's not just one person, giving opinions on issues
19:42:36 <andythenorth[d]> often there's a group consensus, but that can switch back and forth
19:42:52 <andythenorth[d]> for a long time "don't add settings" and "use content" was the main view
19:43:01 <andythenorth[d]> currently that's switching back somewhat to "add settings"
19:43:44 <michi_cc[d]> My personal consensus tends to be more like "just turn it on", unless it is a really, really big change.
19:43:48 <andythenorth[d]> I think the official goal is still "don't add settings"
19:46:07 <andythenorth[d]> I think very many of the settings people want could be done in GS
19:46:14 <andythenorth[d]> but there seems to be an aversion to that
19:46:45 <Samu> i still dont know how to make a newgrf
19:47:02 <andythenorth[d]> it's probably the easiest of the APIs to use
19:47:12 <andythenorth[d]> I wouldn't recommend using nfo though
19:48:25 <andythenorth[d]> superlib gets a random tile like this
19:48:25 <andythenorth[d]> ` // Randomize the station location
19:48:25 <andythenorth[d]> tile_list.Valuate(GSBase.RandItem);`
19:48:31 <andythenorth[d]> why is that the API to random?
19:48:54 <andythenorth[d]> I cannot build any picture of what that is doing
19:48:54 <Samu> you have a list of tiles
19:49:11 *** Wormnest has joined #openttd
19:49:27 <Samu> then you assing a rand value to each tile
19:49:54 <andythenorth[d]> oh I missed a line
19:49:57 <andythenorth[d]> ` tile_list.Sort(GSList.SORT_BY_VALUE, GSList.SORT_DESCENDING); // place the station as far away as possible from the industry location (in practice -> to the south of the industry)`
19:50:27 <andythenorth[d]> but how does it know which list field to sort on?
19:50:45 <andythenorth[d]> I really don't understand valuate
19:51:12 <michi_cc[d]> It sorts on the value (i.e. the thing that Valuate put in)
19:51:38 <andythenorth[d]> isn't the list key/value pairs?
19:51:57 <Samu> valuate is something like this: foreach item in a list, assign a value from the result of 'function'
19:52:09 <michi_cc[d]> Yes. Valuate does `value = func(key)`. There's probably some fancy functional term for this.
19:52:27 <andythenorth[d]> ok so if I've valuated the list, how would I sort on the original items?
19:52:33 <andythenorth[d]> nvm, maybe that's not valid
19:53:18 <Samu> tile 3 gets value whatever
19:53:25 <andythenorth[d]> ok I play tanks again
19:53:33 <andythenorth[d]> everything in GS is one step forward, one step
19:54:38 <andythenorth[d]> I am determined to make a functional GS, but there's so many pitfalls π
19:54:41 <Samu> for (local tile = tile_list.Begin(); !tile_list.IsEnd(); tile = tile_list.Next()) { do something }
19:55:11 <Samu> if you sorted the list by value, that will get the tile with the highest value attributed
19:59:31 <andythenorth[d]> it's just weird
19:59:52 <andythenorth[d]> it's like a built-in lambda sort
20:00:00 <andythenorth[d]> combined with a map
20:00:35 <andythenorth[d]> oh wait, it's just a special purpose map?
20:10:28 <TrueBrain> stop pushing your agenda
20:10:44 <TrueBrain> "died" .. I take offense to that!
20:12:25 <andythenorth[d]> "was left to mature"
20:27:31 <andythenorth[d]> ok so picking a random map tile requires valuating the whole map?
20:34:41 <Samu> you can do it some other way
20:41:51 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
20:45:42 <Samu> I wonder why can't we run DoCommand in test mode in a valuator
20:58:24 <andythenorth[d]> crashed it, again
20:58:32 <andythenorth[d]> can't valuate a 512x512 map
20:59:14 <andythenorth[d]> I think this is why I was walking each tile in a loop, valuator can't be used
21:00:10 <JGR> Why are you trying to do that?
21:01:51 <andythenorth[d]> to get a random tile from the map
21:02:07 <andythenorth[d]> I might just count the tiles, and try to learn squirrel random
21:02:10 <JGR> Just pick a random number from 0 to the number of tiles
21:02:20 <andythenorth[d]> yeah, that would seem more obvious
21:02:31 <andythenorth[d]> I don't understand all this valuator stuff, it seems elaborate
21:02:50 <andythenorth[d]> all the examples are based on it
21:03:16 <JGR> Creating a map structure with every tile in it is invariably a bad idea, it's not what that is for
21:03:45 <andythenorth[d]> it's fine if I walk all the tiles individually and put them in table slots
21:03:49 <andythenorth[d]> but not with valuators
21:04:32 <JGR> Stuff like that is why so many GSs have terrible performance
21:05:36 <andythenorth[d]> it's what the examples show though
21:05:58 <andythenorth[d]> and I'm told we can't add methods for OpenTTD to do things quickly for script
21:06:05 <andythenorth[d]> although opinions vary of course π
21:06:32 <andythenorth[d]> ok so I pick a random number from number of tiles
21:06:37 <andythenorth[d]> but I have to remove the void tiles around the edge
21:06:58 <JGR> If the tile you pick turns out to be no good, randomly pick another
21:06:59 <andythenorth[d]> why do we have a GSList entity, but no way to get a random entry from it?
21:07:42 <JGR> You should not try to create a list of all tiles
21:09:01 <andythenorth[d]> I don't understand how to not deadlock without a list
21:09:12 *** Samu has quit IRC (Read error: Connection reset by peer)
21:09:35 <andythenorth[d]> if I loop over random tiles until the condition is met, then it could deadlock infinitely
21:10:19 <andythenorth[d]> the only way I know of non-deadlocking random is a list of all possible values, and pop one, repeat until list empty
21:12:22 <JGR> In both cases you'll likely want to give up if you can't find anything within a certain number of iterations
21:12:39 <JGR> This is almost certainly smaller than the number of tiles on the map
21:14:13 <andythenorth[d]> maybe squirrel has a random method
21:14:16 <andythenorth[d]> docs don't though
21:14:53 <JGR> RandRange is presumably what you want?
21:14:54 <andythenorth[d]> ok we do the random from our seed
21:16:37 <andythenorth[d]> ok the case is trying to build industry in a specific town
21:17:00 <andythenorth[d]> I considered a spiral walker, but (1) I don't know how (2) it will always bias to a certain compass direction
21:18:01 <JGR> At the risk of being a contrarian, have stuff run fast is more important than small biases, most of the time
21:18:08 <andythenorth[d]> I did patch the client to do this in prospecting
21:18:15 <andythenorth[d]> instead of pissing around in GS
21:18:33 <andythenorth[d]> but I didn't keep that π
21:18:55 <andythenorth[d]> and prospecting that way is very likely to fail, as it may never land on the chosen town
21:19:23 <andythenorth[d]> spiral walker, but randomise the starting compass direction when initialising?
21:19:36 *** Wormnest has joined #openttd
21:24:03 <andythenorth[d]> oh the bias could be avoided by spiral walking to fill a tile list
21:24:12 <andythenorth[d]> then picking a random
21:37:19 <Samu> pick a random tile where the closest town is the town you want?
21:38:08 <Samu> i think there's a GetClosestTown
21:40:02 <dP> th is spiral walk for, even if you want all town tiles for some reason just do bfs
21:40:31 <andythenorth[d]> I know it's breadth-first
21:40:34 <andythenorth[d]> but implement how?
21:41:40 <dP> for x in q: q.extend(children[x])```
21:43:58 <Samu> im trying to make DoCommand work in valuators as long as they're in TestMode
21:45:32 <andythenorth[d]> maybe I'll just flood fill a fricking circle around each town to 64 tiles or something
21:45:44 <andythenorth[d]> then check if those tiles are actually belonging to the town
21:46:00 <andythenorth[d]> this is stupidly hard currently
21:46:14 <andythenorth[d]> all I want to do is place an industry near a town
21:46:52 <dP> because you keep inventing hard and ineffecient solutionss
21:47:12 <dP> bfs is O(town tiles) and just a few lines to code
21:47:28 <dP> you can't get any better than that if you need a whole list
21:47:46 <JGR> Even that seems overcomplicated for what is needed here
21:48:23 <dP> but I ran out of simpler solutions a weak ago :p
21:48:28 <JGR> Put a rectangle around the town tile of a suitable size, randomly pick tiles until success or you give up
21:48:49 <JGR> No lists, maps or complicated data structures required
21:48:52 <Samu> i think he doesn't want to place an industry on the wrong town
21:49:58 <Samu> problem might be the random layout
21:50:32 <Samu> you can't directly chose the layout, you won't know which tile is the one that dictates who's town it belongs
21:51:08 <andythenorth[d]> that issue is definitely an edge case at best
21:51:28 <andythenorth[d]> and FIRS is in scope
21:51:40 <andythenorth[d]> so the industry layout could be worked out
21:52:24 <andythenorth[d]> if I want a circle, can't I just do trig with radius?
21:52:44 <andythenorth[d]> everything I ever wrote in flash games came down to trig
21:52:54 <Samu> DistanceSquare from the tile to the center of town tile
21:53:32 <andythenorth[d]> SquareDistance is ?
21:53:46 <dP> picking a random point in a circle is a bit tricky
21:54:06 <andythenorth[d]> random (360 degrees), random(radius)
21:54:17 <andythenorth[d]> then tan x y or something
21:54:29 <andythenorth[d]> that's how we used to make enemies move around in flash
21:54:31 <andythenorth[d]> or fire bullets
21:54:31 <Samu> dP did something crazy good for the tropic tileset, I still have his commit here
21:54:41 <dP> andythenorth[d]: that will make it likely to pick close to center
21:54:49 <Samu> it generates desert and rainforest based on distsquare
21:54:50 <andythenorth[d]> flash worked in radians, so it had to be converted, but eh
21:55:06 <andythenorth[d]> dP: because of inverse square?
21:55:24 <andythenorth[d]> random(log(radius)) or something
21:55:31 <dP> because there is more area further from ceter
21:57:08 <dP> google says `r = R * sqrt(random())`
21:57:19 <andythenorth[d]> or I can just take a rectangle, and filter out tiles that exceed radius X
21:57:26 <andythenorth[d]> then pick a random one
21:57:57 <andythenorth[d]> ok thanks, let's try version 932 of this
21:58:10 <andythenorth[d]> I preferred the one that copied all the tiles into 300MB of RAM
21:59:02 <JGR> Something, something, round pegs in square holes π
22:08:01 <andythenorth[d]> FML how do I valuate a tile list with GetDistanceSquareToTile
22:08:16 <andythenorth[d]> there must be some syntax for the list item to use as param to GetDistanceSquareToTile
22:08:44 <andythenorth[d]> or I just ignore the valuator
22:08:53 <andythenorth[d]> just write actual code
22:12:15 *** Wormnest has quit IRC (Ping timeout: 480 seconds)
22:16:31 *** keikoz has quit IRC (Ping timeout: 480 seconds)
22:19:01 <andythenorth[d]> GSTile.GetDistanceSquareToTile and GSMap.DistanceSquare are equivalent?
22:19:10 <andythenorth[d]> both take 2 tile indexes as params
22:19:37 <andythenorth[d]> yeah one just maps to the other
22:23:32 <andythenorth[d]> this is returning values in the thousands range
22:23:33 <andythenorth[d]> GSMap.DistanceSquare(tile, GSMap.GetTileIndex(start_x, start_y))
22:24:32 <andythenorth[d]> where the tile is in a rectangle defined by a rectangle drawn 70 tiles either side of start_x, start_y
22:25:04 <andythenorth[d]> how can the distance square be 9800?
22:25:17 <andythenorth[d]> from tile at (100, 100) to tile at (170, 170)
22:25:20 <andythenorth[d]> this is stupid
22:25:55 <JGR> That is the correct value
22:26:29 <andythenorth[d]> it's a 90 degree triangle?
22:26:41 <andythenorth[d]> oh the result is squared
22:26:50 <andythenorth[d]> some things are obvious in retrospect
22:27:05 <andythenorth[d]> "This is the distance is the length of the shortest straight line between both points."
22:27:19 <andythenorth[d]> writing docs is hard, I don't like it either π
22:28:16 <andythenorth[d]> ok calling sqrt on that returns floating point results of course
22:28:18 <andythenorth[d]> is that safe?
22:28:24 <andythenorth[d]> or do I need to use some integer maths?
22:28:47 <JGR> You'll probably find it more convenient to square the other value that you're comparing it with
22:29:30 <andythenorth[d]> probably avoids this π
22:31:14 <andythenorth[d]> broke it again π
22:33:41 <andythenorth[d]> lol what does ^ do in squirrel?
22:33:46 <andythenorth[d]> I tried radius ^ 2
22:33:55 <andythenorth[d]> not sure what it did, but it didn't square it
22:34:04 <andythenorth[d]> anyway, circles
22:34:46 <andythenorth[d]> now I need to convert it to a valuator
22:34:50 <Xarick> I'm doing boring stuff too
22:35:14 <andythenorth[d]> ok on the plus side, I can now make 'nuke a city' much more realistic
22:36:07 <JGR> andythenorth[d]: ^ is XOR
22:36:20 <andythenorth[d]> shows how much programming I've done π
22:36:36 <andythenorth[d]> squirrel just lists it as an operator, no explanation
22:38:47 <Samu> you can't run DoCommands with valuators
22:39:03 <Samu> you wanted an insta area clear?
22:40:22 <andythenorth[d]> does squirrel have named params?
22:40:35 <andythenorth[d]> error when I tried passing keywords, e.g. foo=10
22:41:58 <JGR> named parameters like that is a Python thing
22:42:36 <JGR> Squirrel is not really like Python syntax-wise
22:43:10 <andythenorth[d]> I find that constantly π
22:43:35 <andythenorth[d]> ok let's try a valuator again, I've been told to use them in preference to foreach
22:45:48 *** Wormnest has joined #openttd
22:46:32 <andythenorth[d]> I don't understand how to give the parameters to the function
22:46:35 <andythenorth[d]> `tile_list.Valuate(GSMap.DistanceSquare(tile, origin_tile) <= (tangent_radius * tangent_radius));`
22:46:47 <andythenorth[d]> that should valuat to true or false
22:46:54 <andythenorth[d]> but I need to map `tile`
22:47:02 <andythenorth[d]> like in a lambda
22:47:18 <andythenorth[d]> I tried `_` because that seems to be a magical token
22:47:46 <andythenorth[d]> is valuate really so much faster than foreach()
22:47:46 <JGR> I really don't understand why you are trying to use tile lists at all
22:48:31 <Samu> get_demolish_cost is a function
22:48:37 <andythenorth[d]> because I've been told they're more performant?
22:48:57 <andythenorth[d]> isn't this the intended approach?
22:49:00 <Samu> and u put that function in the valuator
22:49:16 <JGR> Doing the wrong thing in a more performant way will not get you where you want
22:49:18 <andythenorth[d]> I mean, I'd just do a foreach over x,y positions
22:49:25 *** WormnestAndroid has joined #openttd
22:49:47 <andythenorth[d]> there's all these abstractions, and very little documentation
22:50:01 <andythenorth[d]> the only way to learn is to cargo cult from SuperLib, which is at least commented
22:50:29 <andythenorth[d]> this is just basic 2D grid maths though?
22:50:35 <andythenorth[d]> why is all this stuff needed?
22:50:44 <andythenorth[d]> is valuate really so much faster than a loop?
22:51:04 <JGR> You do not need to loop or valuate over all possible tiles
22:51:39 <glx[d]> Valuated list can be filtered, it's nice for decision making
22:51:58 <andythenorth[d]> that's what I'm trying do
22:52:03 <andythenorth[d]> Valuate and use KeepValue
22:52:08 <andythenorth[d]> because that's what all the superlib stuff does
22:52:14 <andythenorth[d]> instead of foreach and conditional
22:52:21 <glx[d]> But doing it on all tiles is 'wrong'
22:52:34 <andythenorth[d]> this is just a rect around a tile
22:53:20 <Samu> then each tile gets a 1 or 0
22:54:13 <andythenorth[d]> is the item from the list just passed to the function as first parameter by convention?
22:55:29 <Samu> the variable tile is the one from tile_list in the valuator
22:55:59 <andythenorth[d]> nah that just crashes
22:56:13 <andythenorth[d]> wrong number of parameters
22:56:57 <andythenorth[d]> would be weird and magical otherwise
22:59:09 <Samu> which function gets the wrong number of parameters, seems correct to me
23:03:25 <Samu> i'm actually surprised why it didn't work
23:06:56 <Samu> ah, i think i figured it out
23:09:21 <andythenorth[d]> weird mix of tile list, but then not valuating
23:09:32 <andythenorth[d]> I'm only using the tile list now because it has the convenient rect function
23:09:42 <andythenorth[d]> I could just work in a loop though
23:10:18 <andythenorth[d]> are tile lists to be avoided?
23:11:30 <JGR> `areas.towns[GSTile.GetClosestTown(tile)].AddTile(tile);`
23:11:42 <JGR> Doing this for every tile is absurdly expensive
23:12:36 <andythenorth[d]> yeah that's not executed in any path right now π
23:12:45 <andythenorth[d]> I ran that and timed it for different map sizes
23:12:49 <andythenorth[d]> I need to delete it
23:13:06 <andythenorth[d]> it's a significant amount of time
23:14:11 <andythenorth[d]> it also bloats RAM, I didn't measure scientifically, but I reckon close to 50%
23:19:39 <JGR> It's the GSTileList which uses up memory
23:19:59 <JGR> GetClosestTown is O(N) in the number of towns but doesn't consume any memory on its own
23:20:18 <JGR> TBH GSTileList seems like a huge footgun from an API point of view
23:21:18 <andythenorth[d]> I wrote a more conventional for loop here, but it still returns a GSList
23:22:36 <andythenorth[d]> TBH I find this easier to work with than the relatively undocumented abstractions
23:22:46 <andythenorth[d]> but I assumed the abstractions were much more peformant
23:23:45 <Samu> or tile_map.KeepValue(0) for the tiles outside the circle
23:23:46 <andythenorth[d]> can I sack off the GSTileList and just put the result in an array?
23:24:19 <JGR> The "performance" comes from the script not being charged for doing really inefficient operations
23:25:12 <andythenorth[d]> hmm seems I can't push to array
23:25:39 *** Samu has quit IRC (Quit: Leaving)
23:26:08 <andythenorth[d]> oh I have to instantiate an array to a specific size?
23:29:29 <andythenorth[d]> ugh how do I create a 2-tuple in squirrel?
23:29:48 <andythenorth[d]> I want to fill an array with x,y pairs
23:30:30 <andythenorth[d]> foo = array(0); bar = array(0); bar.push(x), bar.push(y); foo.push(bar);
23:30:57 <JGR> This seems quite a deep rabbit hole from the problem being solved
23:31:16 <andythenorth[d]> I just wanted to build farms near towns π
23:31:26 <JGR> You don't need to build lists of tiles to do that
23:32:52 <andythenorth[d]> lol squirrel array can't have array as value
23:33:19 <andythenorth[d]> oh maybe there's no array unpacking
23:35:21 <andythenorth[d]> so now I could just pick a random tile from the simple array
23:35:26 <andythenorth[d]> no valuation stuff
23:36:05 <andythenorth[d]> the other route would be just picking random values within the radius, no list
23:37:32 <andythenorth[d]> pick a random x
23:37:42 <andythenorth[d]> pick a random y, limited by trig to be within the radius
23:38:26 <JGR> andythenorth[d]: That is the better solution
23:38:52 <andythenorth[d]> I'm not sure how to limit it
23:39:02 <andythenorth[d]> it needs to not try the same tile twice
23:39:44 <andythenorth[d]> I guess just n tries
23:39:50 <andythenorth[d]> if it fails, it fails
23:40:21 <JGR> As long a n << the number of tiles, re-trying the same tile is unlikely enough that you should ignore it
23:40:58 <andythenorth[d]> the bug reports we used to get about 'your random quiz questions aren't random' π
23:41:12 <andythenorth[d]> or the servers we hung because of unclosed loops
23:41:24 <andythenorth[d]> we != OpenTTD, other places π
23:43:14 <JGR> Sometimes you have to embrace the statistic nature of things
23:44:31 *** nielsm has quit IRC (Ping timeout: 480 seconds)
23:45:46 <andythenorth[d]> if you're faking accounts, make sure to start lots of entries with '1'
23:50:34 <andythenorth[d]> not sure if it's one per town, didn't count π
23:51:13 <andythenorth[d]> looks like it, if I change the radius
23:52:32 <andythenorth[d]> not sure if I actually need to avoid using GSTileList or not
23:52:44 <andythenorth[d]> but I seem to get more done faster using primitives
23:52:54 <andythenorth[d]> in terms of coding it
23:52:58 <andythenorth[d]> even though it's more LOC
23:55:46 <andythenorth[d]> wonder if I can get more timing data than integer seconds
23:56:01 <andythenorth[d]> this is using GSDate.GetSystemTime()
23:57:30 <glx[d]> GSBase.RandRange(xmax-xmin)+xmin and GSBase.RandRange(ymax-ymin)+ymin
23:59:25 *** HerzogDeXtEr has quit IRC (Read error: Connection reset by peer)
continue to next day β΅