Time Nick Message 00:00 MTDiscord I actually tried to do a similar pump thing myself, and if it had worked (and my exploit prevention measures didn't break it) then I would have used that instead of sponges in NC. 00:01 erle wait why didn't it work 00:02 erle i think what can also work is the kansas city shuffle: everyone looks left, but you go right 00:02 erle in gameplay terms, keep the player on their toes by making it impossible to minmax 00:02 erle by fucking up minmaxing gameplay in rare, but catastrophic ways 00:03 erle xpiratez has this thing where a lot of mission have a 5% chance of everyone being dead and zombies being spawned instead, which is a much different battle than against squishy humans 00:04 erle and mindustry has a reactor that provides a LOT of energy, but it takes a huge amount of energy (less than it provides) to start 00:04 erle (mindustry is a tower-defense factory-builder game, if you don't know it) 00:05 erle so if your supply of coolant or fuel lags for a short moment, you'll have a reactor that is a liability instead of an asset 00:06 erle they have also another reactor that just explodes if it has not enough coolant, but that can be mitigated by a) turning it off b) building it close to enemy territory you want to blow up 00:06 erle which is why it gets disabled in multiplayer games, it's a less useful gameplay constraint that can literally be gamed 00:31 MTDiscord Hmm, the thing is that when disaster strikes, I want players to feel like "this is my fault, I should learn from this" instead of something like "oh well can't win 'em all" and so there needs to be a sense that they could really control everything, even if in practice they very much need to decide what's really worth it. 00:32 erle but that's the beauty of it 00:32 erle if disaster strikes in xpiratez it *is* your fault 00:33 erle because it means you either minmaxed or took risks you should not have taken 00:33 erle same for other xcom-engine games 00:33 erle and for battle for wesnoth, btw 00:34 erle you can reliably spot battle for wesnoth noobs by them complaining about the RNG 00:35 erle if you complain, you stop playing. if you see it as a hint that you overcommitted, then you keep playing, more carefully. 00:35 MTDiscord Hmm, maybe... I guess I do encourage players to optimize, but not to overfit. 00:43 erle how though? 00:43 erle i mean the limited inventory is obviously one thing for this 00:47 MTDiscord Limited inventory is one of those features that is very obvious when you first start playing but after you get into the groove of things, has mostly just subliminal effects. 00:47 MTDiscord Like, you get used to the different "economy" where resources are more valuable, and you get used to planning storage in the world instead of on your body. 00:47 MTDiscord So it turns out not to be a thing you really struggle against for long. 00:48 MTDiscord Optimization is more like realizing that there are better and worse ways to manage a tree farm, and better or worse ways of handling a charcoal supply. 00:49 MTDiscord Overfitting though happens when you over optimize a machine for a specific task end end up hurting it's reliability when adverse conditions crop up. 00:54 erle Warr1024 what adverse condition can crop up though? 00:54 erle i mean there is no weather, no creeps or so 00:54 erle in mineclone2, lightning might strike your treehouse and it burns 00:54 erle or a creeper explodes you 00:56 MTDiscord Timing can be adverse. Without completely rewriting MT to do like a fixed 20Hz tick thing like MC does, there's no way to guarantee that basic game mechanics aren't affected by lag. 00:56 MTDiscord I have come to interrupt your current conversation to talk about mac os 00:56 MTDiscord Also, the fact that players rarely ever just build a machine and then do nothing else can be adverse. Just making nearby changes risks affecting other things. 00:57 MTDiscord The first rule of mac OS is you do not talk about mac OS. 00:57 MTDiscord The second rule is that a closed sytsem will tend toward maximum entropy. 00:57 MTDiscord 20hz? My friend, it is 20 ticks 00:58 MTDiscord 2b2t had issues with it going down to 0.02 ticks or whatever 00:59 MTDiscord Yeah, 20Hz, like I said. 00:59 MTDiscord 20. Ticks. 00:59 MTDiscord https://tenor.com/view/dog-funny-fun-beautiful-beauty-gif-17043663 00:59 MTDiscord Uh, wow, do you ... not know what Hz is? 00:59 MTDiscord That's it, we need Minecraft unrehab on the discord immediately 01:01 MTDiscord I don't really know if I'd go with 20Hz anyway. NC Optics run at 12Hz, which I chose because it was a good compromise frequency that could, if someone had a powerful enough machine, run butter-smooth at an exact number of frames at common display refresh frequencies. 01:01 MTDiscord So far though it rarely actually runs smoothly in real-world systems. 01:01 MTDiscord I have no idea why mc server step runs at 20hz but it's pretty dumb because it still lags lmao 01:02 MTDiscord One of NodeCore's principle is that everything in the world can experience the flow of time and interact with its environment, and that can be pretty costly in terms of ABMs. 01:03 MTDiscord Running a fixed number of ticks per second that represent a fixed amount of in-game time means that you can no longer guarantee that the in-game time stays in lockstep with IRL time, so people may experience the flow of time in-game slowing down, but because you're doing fixed size chunks of time each step, it makes it possible to do in-world physics reliably and repeatably. 01:03 MTDiscord Have you considered offloading it into a pure memory simulation and having an lbm listener thing or something 01:04 MTDiscord The map can't hurt you if it's a second class citizen of your logic 01:04 erle i agree here 01:04 erle (actually not) 01:04 MTDiscord Variable-step-size physics engines try to account for this by doing all the necesssary calculus, but somebody always ends up cutting corners, like doing only 1 collision check per step, so now the frequency of collision checks is variable. I found that the simplest corner to cut is just running fixed-size time chunks. 01:04 erle this is the same logic that people use to build a virtual DOM because they hate the real DOM 01:05 MTDiscord Well people aren't usually walking around and mining a dom lmao 01:05 MTDiscord I seem to remember one developer who "virtualized" redstone computations and said that it was amazingly fast, but then when I tested it, it turned out that it was only insanely fast because that dev's personal computer was insanely fast, and it performed about the same as comparable systems in a side by side comparison. 01:06 MTDiscord There is another thing though 01:06 MTDiscord About the closest I've come to a "virtual DOM" kind of thing is doing separate plan-and-commit phases, so that I can make the new state depend solely on the past state, without the new present state mixed in. 01:06 MTDiscord You can also simulate while chunks are unloaded and flush with lbm 01:07 MTDiscord It can't change layout if the map ain't even there 01:07 MTDiscord Or can it 01:07 MTDiscord https://tenor.com/view/vsauce-evil-mastermind-vsauce-evil-mastermind-gif-27579269 01:07 MTDiscord Haha, simulating stuff happening in unloaded chunks, how would I go about doing that? I'd need some way to keep the relevant chunks in memory ... oh wait, I feel like there's a system that already exists for loading chunks into memory... 01:08 MTDiscord If I can't afford to keep the chunks actually loaded then there's not much value in "simulating" them. 01:08 MTDiscord Yes, but you are loading the entire memory, into memory, not just logic paths 01:09 MTDiscord So you're saying that I should load only very specific things in memory and allow time to freeze for other things? That's almost exactly the bug I'm trying to fix. 01:09 MTDiscord What if you have a line that goes through like 10 chunks, you've just loaded in x x y x z x i - line blah blah blah instead of what you are doing 01:09 MTDiscord I'm okay with the flow of time varying from area to area, but it should vary only by area, not by random properties of the materials. 01:10 MTDiscord No, minetest is single threaded, it's gonna freeze anyways, it will just lighten the load 01:10 MTDiscord Or is it 01:10 MTDiscord https://tenor.com/view/vsauce-evil-mastermind-vsauce-evil-mastermind-gif-27579269 01:10 MTDiscord It's not really the threadedness of MT that's the problem; a lot of it is just the idiocy of the ABM timer. 01:11 MTDiscord Oh yeah lmao, yeah doing a memory simulation would totally fix that 01:11 MTDiscord Abms are about as predictable as I am 01:11 MTDiscord What I would want is an ABM timer that uses all the unused CPU cycles left on the table by other game mechanics to run ABMs continuously. What I get is one that freezes the game for 200ms every second, and then the game ends up sleeping much of the rest of the 800ms left. But if I increase the ABM budget, while I use more of the available CPU to do useful work, I also get a bigger lag spike. 01:12 MTDiscord ABMs are almost exactly what I actually want, because the feature that they're skipped when CPU is under stress is something I actually WANT. 01:12 MTDiscord What if the entire area is abms? The game is gone lag 01:13 MTDiscord It would be nice if I didn't need "patrol ABMs", i.e. where I have to have an ABM scanning an area for nodes just to make sure that none were leaked by LBM and such logic, just to add them to a queue to be checked on a globalstep, or regenerate missing node timers. 01:13 MTDiscord Gotta scan, gotta process, hopefully the game engine scans on chunk load 01:13 MTDiscord It'd also be nice if ABMs could be prioritized or weighted/balanced... 01:14 MTDiscord You'd have to create a step budget with lbms and craft your own in Lua if you want to fine grain or else you are at the mercy of the minetest gods 01:14 MTDiscord Self-healing is an important property of NodeCore. There are not allowed to be any of the "oh, the node timer got lost due to a crash? Just dig the node and place it again" kind of bugs. It's the game's own responsibility to fix its own internal consistency, at least beyond the point where the engine can corrupt the entire database itself. 01:15 MTDiscord Is this a stateful or stateless logic environment? 01:15 MTDiscord dunno what you mean by "state" here. 01:15 MTDiscord Are your abms influenced by environmental factors? 01:16 MTDiscord Not sure what you mean; isn't "environmental factors" kinda the whole point of ABMs? 01:17 MTDiscord Nah, you can just run random stuff just being loaded. Is the consummate function that you are passing into the minetest registration api checking the area for anything? A block, a person? Entities? 01:17 erle Warr1024 the plan-and-commit thing is neat. do you have this as a separate mod somewhere? 01:17 MTDiscord Almost always, yes. 01:18 MTDiscord Plan-and-commit isn't a specific mod, or even a specific implementation; it's more like a design pattern that I apply in a number of situations. 01:18 MTDiscord Stateful, hmm, yes that is quite tougher then 01:18 MTDiscord Like you can see examples in the nc_optics api.lua, and in klots, I think try_move_klot.lua or something. 01:19 MTDiscord So you're just moving a thing to a thing in that scenario? Is this consuming excessive amounts of cpu cycles? 01:19 erle Warr1024 how do you plan-and-commit with ABMs in general? 01:20 MTDiscord Everything in NodeCore can "tick". Nodes can tick. Items can tick, in stack nodes, in player inventories, inside falling node entities or item entities. Any mod can register interactions; this necessitated me replacing node timers with my "delayed node trigger" system that lets you register multiple independent timers like the way ABMs are registered. 01:20 erle oh hmm 01:20 erle node timers? 01:21 MTDiscord I don't think it's the timing function 01:21 MTDiscord I think this is abusing the translation glue between Lua and the C++ code 01:22 MTDiscord I don't do plan and commit "with ABMs" exactly, but it's more like I have a globalstep process that runs things either every step, or on some set interval, and the involvement of ABMs there is to find stuff to add to the queue to process there. For example, nc optics are added to the optic_check queue every time you place, modify, etc an optic, any time a beam is applied/removed to its faces, each time the optic is loaded via LBM, and 01:22 MTDiscord randomly by ABM to make sure that there are no indefinitely "stuck" optics in inconsistent states. 01:22 MTDiscord Node timers are a mess because there's no way to register a node in mod A, register a node timer callback in mod A, and then add a second node timer with a different delay and callback in mod B. 01:23 erle they also represent memory leaks if used for fire etc. 01:23 erle node timer on air when 01:23 MTDiscord Mods need to be able to add behavior to existing materials. 01:23 MTDiscord Because you are accessing the map in Lua, you are not accessing the map directly at all, you're telling the underlying api to tell the engine to get the thing, then it got it, now pass it back to the api, but make it so Lua can understand it, then your Lua code does work with it 01:24 MTDiscord I am, quite unsure of a way to improve this engine wise 01:24 MTDiscord heh, yeah, node timers are also expensive compared to ABMs. ABMs cost the CPU to find nodes, but node timers cost memory to store timer state for them AND the CPU to eventually fire them. If you have a rule like, say, "dirt needs to check for nearby grass to spread onto it" then I bet you can make node timer implementations easily worse than ABM ones. 01:24 MTDiscord Precisely 01:25 MTDiscord I do not know if abms are a pure Lua construction or if it is integrated into the engine code 01:25 MTDiscord I messed around with trying to improve ABM performance overall and wasn't able to do much. The one thing I found is that if you have a "neighbors" check, your ABM is roughly 7x as expensive as without. 01:26 erle Warr1024 that's an interesting bound for how much your check has to improve on running less code 01:26 MTDiscord If you only care whether the node has the right neighbor anywhere around it and not in one specific place, or if nodes that actually have the necessary neighbors will be the minority, then it may make sense to use it, but if you e.g. want to check for grass that has dirt above it, then the neighbor check is probably counterproductive, since you'll pay the price, hit the action most of the time anyway, and still need to check that one 01:26 MTDiscord node again to see if the thing you expected is in the place you expected. 01:27 MTDiscord I haven't actually benchmarked checking the 26 neighbors in lua, but I imagine it's probably worse in many cases, and better maybe only in a few. 01:27 MTDiscord But it's better if possible to avoid the need to check for neighbors at all if possible. 01:28 MTDiscord Solution: abm cache, update stateful cache based on requirements, if requirements unmet, abm does not exist in memory, yet, or, at all 01:28 MTDiscord Very complex issue 01:29 MTDiscord One fun thing I did was an "invert neighbors" hack in NodeCore which I found did seem to speed things up in most cases (though it trades off the risk of worsening them in less common cases). Instead of registering an ABM for common node A with rare neighbor B, it internally registers it for rare node B with common neighbor A (thus reducing the primary hit rate before the neighbor check) and the logic then internally handles the inversion 01:29 MTDiscord and calls the action the other way around. 01:29 MTDiscord Yes that is what abms were primarily designed for 01:29 MTDiscord It's not exactly equivalent, though, so e.g. with grass spread, being inverted, it tends to trigger the ABM randomly in a 3x3x3 area, since the randomness is applied before the inversion. In practice, I've noticed it but I don't really mind; still seems worth it. 01:31 MTDiscord The one thing I use ABMs for that they're really not designed for is patrolling. I scan the map for things that are supposed to be in some other queue, or have some other timer set for them, but got "lost". It's a shame that it's such a big price to pay for an 0.001% kind of case, but when those cases actually happen, it really sucks if there's no way to ensure they get fixed. 01:31 MTDiscord Grass spread can be triggered with a timer, if it is an abm, you will get excessive slowdown 01:32 MTDiscord I think you've probably got that backwards. How is registering a timer for every grass node not the chaos route? 01:32 MTDiscord No, you register the thing grass spreads to to check if it should start the timer when it's constructed 01:32 MTDiscord Stateful initialization 01:33 MTDiscord That ... sounds pretty horrible. 01:33 MTDiscord One second 01:33 MTDiscord Like, complex, and then you eat up the node timer for the thing on grass spread. 01:33 MTDiscord https://youtu.be/d_gbNApq46c?feature=shared 01:33 MTDiscord tbh the whole "only one timer per node" thing is just horrendous. 01:34 MTDiscord I am not telli telling you this because I am guessing, I am telling you this because I tested around 50 different implementations over the span of 4 days lmao 01:35 MTDiscord give that you were making an MC beta clone and that grass spread was one of the few mechanics that version had that would make much sense to do as an ABM, yeah, that probably could have worked out well for you. 01:35 MTDiscord NodeCore has so many ABM-driven mechanics that it has to multiplex ABMS to avoid breaking the ABM cache. 01:36 MTDiscord No I'm not talking about anything else besides your grass spreading 01:36 MTDiscord That can remove a surprising amount of lag 01:36 MTDiscord I've checked the lag sources and grass is sort of middling. 01:37 MTDiscord Radiation sources and I think sponge growth were more concerning. 01:37 MTDiscord I was going to switch sponge growth to a queue-and-globalstep system, since a lot of the checks are duplicate (same colony triggered by a different node within the colony) and I could easily dedupe that. 01:38 erle jordan4ibanez do you have a writeup of the timer thing 01:39 MTDiscord I only have source code, very unfortunate 01:39 MTDiscord This was more of a development in pure anger 01:39 MTDiscord Same with sand 01:39 MTDiscord Really would be better if they just fixed ABMs instead of making us do all kinds of bizarre gymnastics to work around them. 01:39 MTDiscord Sand is a reflective state update, like dominos 01:40 MTDiscord Yes 01:40 MTDiscord EXACTLY! 01:40 MTDiscord But that will require engine work, more engine, less api 01:41 MTDiscord ABMs do have one irreplaceable property, in that they're the only mechanism that's guaranteed eventually consistent independent of other factors so long as the node is within the active area. 01:58 erle jordan4ibanez where is the code though 01:58 erle Warr1024 the words “eventually” and “consistent” do a lot of work here 01:59 erle (that is not part of their day job) 01:59 erle i wish LBMs were fixed 01:59 erle they sometimes do not fire 02:00 erle good night 02:03 MTDiscord "eventually" and "consistent" are not 2 separate words doing 2 separate jobs, they're a single thing here: https://en.wikipedia.org/wiki/Eventual_consistency 02:05 MTDiscord Heh, also thanks for acknowledging that LBMs aren't 100% reliable ... I can't remember anybody else ever having acknowledged that... 03:03 MTDiscord Command sent from Discord by Sr Spookology Coordinator: 03:03 MTDiscord !tell erle https://github.com/jordan4ibanez/Crafter/blob/master/mods/main/nodes.lua#L280 03:03 MinetestBot MTDiscord: I'll pass that on when erle is around 03:15 DeepThgt so, anyone intimately know the physics of default mt game? 03:15 DeepThgt specifically, how many layers of water needed to slow you down from a 1000 block fall and not die 04:27 muurkha erle: yes, often many choices are possible, and more or less equally good, within the constraints; once made, those arbitrary choices themselves become new constraints on future choices. that's both path dependency and a choice that reduces the solution space in the future. a railroad gauge is a good example. if you don't pick a railroad gauge, you can't build either rails or cars, but there's a 04:27 muurkha broad range of reasonable possible railroad gauges. in the future when you know more, you are sure to see that whatever choice you made with less knowledge was suboptimal 11:24 MinetestBot 02[git] 04Desour -> 03minetest/minetest: Fix forgotten CLANG_MINIMUM_VERSION update 135e0f142 https://github.com/minetest/minetest/commit/5e0f14266d42b52c6a67bc1dc104f6800ddacfd8 (152023-10-14T11:23:17Z) 13:34 erle hey rubenwardy Warr1024 luatic what minimal lua unit test setup can you recommend? (yes i can google myself, i want only stuff you have good experience with) 13:34 MinetestBot erle: Oct-14 03:03 UTC https://github.com/jordan4ibanez/Crafter/blob/master/mods/main/nodes.lua#L280 13:34 erle uWu whats this 13:55 BuckarooBanzai erle: i can recommend busted and/or mineunit (https://github.com/S-S-X/mineunit) 14:58 MTDiscord erle: for pure lua, i sometimes use just pure lua (e.g. assert + utils like table equality checking, which modlib provides). i've also used busted outside of minetest, works well enough. 15:12 erle luatic how is modlibs stuff different from luassert assert.are.same({ table = "great"}, { table = "great" }) 15:12 erle https://github.com/lunarmodules/luassert 15:19 MTDiscord erle: for once, i didn't care about as much about helpful output; for two, if you choose the right modlib table comparison function, it may be much more efficient in the worst case. 15:20 MTDiscord for one* 15:21 MTDiscord (specifically, when testing serializers with pretty much random arbitrarily cross-referential table structures, luassert croaks) 15:38 rubenwardy I use busted 16:36 erle > random arbitrarily cross-referential table structures 16:37 erle repent, sinner! 16:40 erle public service announcement: install earlyoom. i just found out that pngcrush can take a long time, but optipng will fill your RAM. 16:51 erle (earlyoom kills stuff that misbehaves before the OOM killer kills other stuff instead) 18:49 MTDiscord erle: PSA: don't install earlyoom, and if you do, don't forget about it 18:51 MTDiscord (background: i installed earlyoom one night (?) and forgot about it so it was killing my processes (everything from thicc editor windows to browser tabs to minetest release builds, most recently) and i was wondering why; i did vaguely remember that i installed an oom killer (but forgot what it's name was) and i did track it down and disable it in the end, though) 19:44 MTDiscord No please, erle I never committed the code that put the check at the be beginning too 😂 20:33 erle luatic you get a message per second in syslog, that's not too hard to miss 21:15 DeepThgt YAY it works! my newest creation splits a stream of items 3 ways equally 21:15 DeepThgt (technic) 21:32 MTDiscord erle: i'm not saying it wasn't a skill issue on my part 21:33 MTDiscord but i def. found the behavior of it just killing random processes more annoying than useful 21:33 MTDiscord yeah an OOM could be even more annoying but i think most of the time i would've managed 21:34 MTDiscord (well, "random" processes is inaccurate. ofc it kills the memory hoggers. but still, pretty poor UX if you ask me. at least, i don't know, a notification would have been nice.) 21:34 muurkha luatic: it's sort of inseparable from overcommit 21:35 muurkha and fork without overcommit can be pretty painful 21:35 muurkha at least on Linux it is 21:54 erle luatic it does not kill just random processes 21:54 erle and the kernel OOM is even worse 21:54 erle because the fun-haters behind chrome adjusted the OOM score so high 21:54 erle that it gets killed first haha 21:55 erle (at least that was true at some point) 21:55 erle muurkha how do you even fork without overcommit?