1. 9

    Interesting take. It sounds like the author of Godot is very comfortable with OOP and it’s been working so far, so why stop doing something that is working?

    Writing many things with the ECS pattern can definitely feel more verbose than inheritance in my experience so far, but Rust doesn’t really make inheritance possible, so an ECS approach makes a lot more sense.

    It was a shame that the main thing the author pointed at was the generic “Node” base class at the center of Godot and didn’t really go into detail on how you would solve problems in both Godot and in ECS.

    For example, if a soldier enters the enemy base for more than 10 seconds they capture it. In ECS, I would create a system for checking if a soldier is in a base “SoldierInBase(Base)”, then I would add a system for checking whether the soldier and base are on opposite sides with a start time “SoldierInEnemyBaseSince(Time)” then a final system for SoldierCapturedBase that would look for any “SoldierInEnemyBaseSince(Time)” for over 10 seconds.

    What would any of that have to do with inheriting from the Node class?

    1. 5

      Writing many things with the ECS pattern can definitely feel more verbose than inheritance in my experience so far, but Rust doesn’t really make inheritance possible, so an ECS approach makes a lot more sense.

      Interestingly, one of the most popular language bindings to Godot is Rust which makes inheritance work with a bunch of macro magic.

      The example you gave allows to show quite well how Godot makes it easy to use both composition and inheritance. In Godot for that I would make a Node Capturable that inherits from a Timer, that has on_area_enter and on_area_exit methods which get connected to corresponding signals of Area that covers the capture zone. The methods would check if whatever entered the base are eligible to cap it (via classes or methods, doesn’t really matter) and if so would start the Timer. It would then emit a captured() signal when capture is complete. Some of the benefits this gives is the easy extensibility, e.g. if I wanted the capture speed to change with the number of soldiers, or blocking the capture if a friendly soldier is in the area, I could do that with a few lines of code. To use it, you would add the Capturable node to the scene tree of a base and connect the area accordingly.

      What would any of that have to do with inheriting from the Node class?

      Node class in Godot allows inclusion into the scene tree, and is the main way composition is done. Node actually inherits from Object, which is the “real base class” that everything inherits from, but it is less often used. Every Node object in the scene tree gets processing calls every render/physics frame, handles pausing, etc. which allows you to quickly add behavior to your game without worrying about interfering with pausing or destruction, etc. as that is handled by other systems.

      1. 5

        The difference comes into play when you’re inheriting, extending or overriding behavior. Your example in OOP would involve for example inheriting BaseCapper. So far, no big difference. But what if you want to customize that behavior? In OOP, you might for example override canCaptureBase(), which decides if a soldier is allowed to capture at a given moment. In ECS, you’d have to have a tag component CanCaptureBase that is added or removed by the system that handles this condition.

        It doesn’t seem too different, but in OOP it’s much easier to see what’s being overridden where: I can take a look at BaseCapper.class to see exactly what inherits it and trace back its different uses. Under ECS, there’s not an easy to see what would happen with a given entity, since components can be added or removed to it at runtime by arbitrary systems. In your example, there’s no easy way for me to know that an entity created in one system would eventually be the target of SoldierCapturedBase, since it might have to be processed by System A to gain CanCaptureBase, then System B to gain SoldierInBase, etc.

        Simpler example: It’s a lot easier to override an “onPlayerHit()” method than PlayerHitSystem.

        I’m generally not a fan of OOP and have spent years evangelizing against it. I’ve been doing a lot of ECS work and lately I’m coming to appreciate the points raised in the article. Namely, if you don’t need the performance benefits, OOP might be easier to work with. Despite OOP’s legendary verbosity, it can be a lot more concise than ECS (where you might have to declare several components and systems, and constantly repeat iteration boilerplate).

        1. 3

          Your example was very interesting! Is there a place where I could read more about example ecs systems and best practices in general?

          1. 2

            If you don’t mind a focus on Rust and have a bit of time, I really liked this talk draft, which approaches ECS from a data-oriented programming direction.

            Lots of glorious nitty-gritty details in this one.

        1. 1

          That last command docker system prune --all --force --volumes freed ~40GBs for me, nice 👍

          1. 3

            I’m working on something very similar to this. The main problem I want to solve is splitting the index into chunks, and doing so dynamically, if it’s needed when something gets added to the index.

            1. 4

              One thing I toyed around with was creating different index files based on part of the hash of the key. This way it’s deterministic (e.g. you might not need to update all indexes if you’re adding one word). You can also alter the “split factor” if you need smaller indexes.

              e.g. in Python:

              import hashlib
              indexes = {}
              
              key = 'cat'.encode('utf-8')
              key_hash = hashlib.sha256(key).hexdigest()
              
              split_factor = 3
              # use this to choose the index
              
              print(key_hash[:split_factor]) # "77a"
              
              1. 2

                I went with splitting the alphabet space, for example 00000-zzzzz space can be split into two buckets, something like 00000-ddddz and ddddz-zzzzz (or whatever the boundaries are). I have zero proof for this but I thought it might help when the user is making related queries.

                Edit: I’m planning to allow chunks to get chunked again, that solves the imbalance you might not have with the hash based approach

            1. 1

              Cool problem domain! It feels like you’re just scratching the surface. I’m hoping someone can take this exploration further and apply it to other problems.

              1. 2

                I’d like to try this with more things but the problem is that AI tools, environments, and simulators usually work with Python. There’s almost nothing for Rust. OpenAI Gym is a fantastic set of simulators but I couldn’t find a way to integrate it. That requires you to write most of it from scratch.

                I might continue working on this at some point in the future but for now it’s on the shelf.

              1. 1

                I’m working on something very similar to this. It’s a NEAT implementation in Rust, along with a few simulators for testing. Here’s a couple of tweets about it https://twitter.com/SGolemac/status/1344019155092205571

                I hope I’ll write something longer soon, possibly a proper blog post.

                1. 3

                  I’m writing a neuroevolution framework in Rust. It’s all from scratch, down to the neurons and synapses. I achieved the first milestone the other night, it managed to evolve a XOR solving network.

                  1. 1

                    Neat! ;)

                    1. 2

                      Yep 🙂 Will try to extend it to hyperneat somewhere down the road

                  1. 1

                    https://sgolem.com

                    It’s minimal. I have plans to put a few more things in there. Thinking also about making it completely static with https://getblades.org, no JS. 🤷‍♂️

                    1. 2

                      It’s quite good.

                      Few nitpicks: not clear where “follow me” leads to; the code background seems too dark to me (both inline and block code). In “Halite III Bot Development Kit in Rust” table of contents has big margins between different entries. Some code blocks have horizontal scroll bars. IMO if you are planning to display lots of code in the posts, a slightly wider width would be better.

                      1. 1

                        Thanks! There are some good points there. I haven’t styled the TOC at all, after plugging it in I didn’t have time, now I’m lazy.

                        That protocol code snippet in the post has a reaaally long line in it, that’s why it’s a mile wide. I’ve come across considerable evidence that the things are much more readable when the lines are short (here limited to ~50ch).

                        Also, scrolling horizontally is very ergonomic on trackpads, but you’ve now made me think about mouse users. I’ll reconsider.

                        Btw I like your site, a little bit too wide for my taste, but very nice and clean! I’m a fan of those simple charts.

                      2. 2

                        Your site is like my site, but better :)

                        no JS

                        Do it, you will thank yourself.

                        1. 1

                          Thank you! Your site is also very pleasing to the eye! I’m investigating my options atm, not really happy with any solution. I’m amusing myself with the idea of writing yet another SSG.

                      1. 2

                        This article reminded me of https://radicle.xyz . Looking forward to see what they will build.

                        1. 1

                          It’s probably not that simple but shouldn’t https or TLS make DPI useless? How can they inspect something that’s encrypted?

                          1. 1

                            That only works until the censor installs its CA on your end device. Alternatively the censor might resort to SNI blocking, and you are out of luck.

                          1. 1

                            Huh this looks like a really convenient setup. My blog (if you can call it so, heh) is generated by ugly shell+awk combo I wrote. Everything is handwritten. It even uses a custom flavour of markdown. Basically I have directory with some 2020-06-06.md files, and a simple shell scripts load the markdown and build everything - the blog pages itself (which is just simple html file), index file (just a list of aforementioned blog pages), and very basic kind of javascript search (user can search via tags, without the need to have any backend).

                            I don’t need any setup, it’s just literally git clone away form working on any linux box, without the need to configure anything at all. And while the way the scripts are written, new features can be added easily (someone emailed me about lack of RSS, and I got it working from scratch, in awk, in under an hour), they get messy quick. And while I love the simplicity and that getting it work is possible under a minute (I use it for more things, for example for rendering my journal to html), I think like it’s slowly getting out of my control. I’ve thought of either rebuilding it in real programming language or switching to some static page generator. So thanks for this post!

                            Btw, consider using CSS prefers-color-scheme. It allows user to specify the preferred theme (light/dark), and lets websites adapt to the settings. It’s really convenient, not that hard to set up if you have sane CSS, and it boosts user experience a lot. All of my websites use this, and I am pushing pretty heavily when some site doesn’t use it. It is just great when you setup your OS to dark theme, and running applications as well as running websites instantly change their appearance to match the OS (and daytime).

                            1. 1

                              Dark mode is on my list, among other things, so I’m definitely adding that! Thanks for the tip 👍🏼

                            1. 1

                              I really like it. I might have a go at making a Jekyll theme based off your CSS.

                              1. 2

                                Please do! It’s very similar to rauchg.com, I like minimal blogs and that one was the main inspiration for me. This one is also good yoshuawuyts.com .

                              1. 21

                                If I’m building a static site for a blog, I think the number one requirement will be stability of dependencies over time. I should be able to come back five years later and get it up and running without spending a day fixing all the broken things.

                                Given my experience with NodeJS, I do not think it meets that standard. I’d probably give Ruby a pass too.

                                Maybe something built on Rust or Go would be my first choice, since they build a single executable and don’t depend on a packaging environment to run.

                                1. 5

                                  I’m pretty happy with hugo and Netlify. I seem to be averaging a post a year lately, but my handful of shell aliases and locally installed static binary for hugo are working fine.

                                  The only trouble I’ve had was that I used a theme as a git submodule and the author removed the upstream repo. Which just convinces me to remove even more dependencies.

                                  1. 3

                                    I built a blog with Hugo back when it was new, then came back to it a few years later and Hugo wouldn’t run (some incompatibility between Go and macOS), updated Hugo, and everything broke because they’d changed so many things with e.g. theming. I did get it working again, but it took a while.

                                    1. 4

                                      Ah, well, there you see my secret. I’ll just never update Hugo!

                                  2. 4

                                    I tend to agree. I wrote up a really nice SSG setup I put together with Flask, Jinja2, and Markdown, and a super simple Flask plugin called Frozen-Flask (for generating static HTML from Flask routes), which one can easily vendorize.

                                    https://lobste.rs/s/s91ry0/most_dynamic_static_site_you_ll_ever_see#c_jrzsib

                                    The nice thing about Flask and Jinja2 is that they are completely ubiquitous as a web app and template framework in the Python community, and its maintainers have essentially declared the projects “done” (+/- the odd security fix). Thus, coming back to a repo built with this setup years later, stuff Just Worked.

                                    Sometimes it’s best not to let perfect be the enemy of the good.

                                    1. 2

                                      I have some projects on Vercel / Zeit that are 3-4 years old, no problems with them whatsoever. It does lock you in a bit but it’s not a big deal since you can always next export.

                                    2. 1

                                      I mean my setup also fits the bill as it would have worked fine (except for markdown processor and rsync) in the 1980s.

                                      1. 2

                                        You’ve probably moved computers a few times since then. How much effort does it take to get the project up and running without the original dev environment? That’s my biggest concern regarding continuity.

                                        1. 1

                                          Well, you need a UNIX-like machine, a server with bunch of headers and footers of indexes and atoms (which I have for my blog) then just have some processor (I did not have this setup since the 80s as I wasn’t back there nor Atom/HTTP was :), I said 80s for hyperbole’s sake and the fact that most of the setup is through basic ed commands and Bourne shell (not bash) syntax).

                                          Ed sadly is less and less preinstalled in modern UNIX-like machines, but ed syntax has not changed for longer than majority of solutions here exist.

                                          I believe that Lindy effect is a good guide for designing such projects (continuous). Would it work right when the internet began - in my case, except for rsync and markdown, which are both just variables for generating html, which could be replaced with something else.

                                          1. 1

                                            That sounds like an extremely boring solution that will probably outlive me ;-)

                                    1. 3

                                      I’ll be honest, I get the idea, but personally I am way more conservative (is that a right word for this) in building my blog. I do not get reasons why would this need to be so convoluted with dependencies on node, etc. but again, I am a UNIX madman. Anything can be easy on the eyes with your own choice of 10 or so lines of CSS.

                                      On my blog everything is done by a shell script, again static, and also I manage to have a gopher site and a gopher atom feed.

                                      I would hate on your page if it did not render in glinks, but as it does… whatever, it’s a blog - if it works and is readable on ereaders then its fine by me.

                                      1. 3

                                        On my blog everything is done by a shell script, again static, and also I manage to have a gopher site and a gopher atom feed.

                                        I had a look at the script – it seems awfully like it would drive on and potentially upload a partial or corrupt version of the blog in the face of the failure of any the commands that it runs?

                                        1. 2

                                          That could apply to any code and that is something you accept and suppose. That is why you have backups.

                                          1. 2

                                            I guess? You might want to investigate the errexit and pipefail shell options, is all.

                                            1. 2

                                              Pipefail does not exist in dash(1). I take responsibility for my choices, and all the problems I’ve had with this setups resulted from my own laziness of not reading the specifications of the standards. Other than that, over past 2 years it has been a trusty and reliable setup that works both on http and on gopher.

                                              Anyways, I’ll set -e as that does not hurt :).

                                              1. 4

                                                Sure! I would venture, though, that this is one possible answer to why people might prefer a more complex body of software; e.g., if that software checks for and handles errors in all of the operations it performs which can fail, is structured to ensure the system only moves from one well-defined state to another, etc.

                                                1. 2

                                                  So why hamstring yourself to dash? To guarantee compatibility with a random /bin/sh should you ever port to a long dead platform? (Except Solaris of course, where /bin/sh wasn’t posix compatible anyway). Bash has been a de facto standard and available almost everywhere for decades.

                                                  1. 1

                                                    It allows for most compatibility in terms of code. It would run on ksh (and I use openBSD a lot in my setups) and on zsh and on bash.

                                                    1. 1

                                                      It sounds like your answer is “because I like the challenge” which is perfectly fine, just be aware to yourself that it’s why you’re doing it.

                                          2. 2

                                            I would do the same if it wasn’t for the math I want rendered statically. I use KaTeX for this (and remark to parse the markdown). I’m not a fan of node.js and javascript in general, but it’s fine for this purpose, I guess.

                                            1. 1

                                              Wouldn’t it be better to use HLatex which would then have some sign character and just connect the output of two preprocessors into one nice single solution (I have no experience with HLatex though, just was looking of how it would be done).

                                              1. 2

                                                I’m not familiar with HLatex and the only things I can find are packages to generate LaTeX files in Haskell, and to use Hangul (the Korean alphabet) in LaTeX. Neither are what I want.

                                                What you’re describing (using a sign character and merge the output of two tools) is basically what I’m doing: https://github.com/rubenvannieuwpoort/static-site-generator/blob/master/scripts/format-blogpost.js#L71

                                                (Not the most easy-to-read code, but the idea is that I use a regex to extract inline and display math to a separate array, and replace them by a signal character in the text. Then I process the array and the text seperately and replace the signal character by the entries of the array)

                                            2. 2

                                              It’s like we are from different planets. I run a little static blog myself, and I understood barely half of this. I’m from a completely different culture.

                                              1. 4

                                                The original post gave me the same feeling. To me, that site looks like it’s written in very simple, plain HTML, without any interactivity or complex styling that would make it difficult or even onerous to write by hand.

                                                It is, in fact, an artifact of an alien culture, produced by intricate machinery that I’ve never heard of.

                                                1. 2

                                                  What do you mean, in reference to what?

                                                2. 1

                                                  Yeah I understand, nothing wrong with a shell script if it does its job. I did think about doing something similar, not that barebones though, a generator like Zola maybe. That would produce an even smaller site but I’d still need to figure out where and how to deploy it. ci/cd, etc. This was basically the easiest thing I could do considering I do React for a living.

                                                1. 1

                                                  Thanks for letting me know the link was wrong on the previous submission 👍🏻 Btw when you click “Fetch title” in the “Submit Story” form it deletes everything after the root /. Can I report that anywhere?

                                                  1. 3
                                                    <link rel="canonical" href="https://sgolem.com">
                                                    

                                                    Fix your metadata. Or just remove the canonical line entirely; you usually don’t need it.

                                                    1. 1

                                                      Oh I’d never remember to check that. Thank you!

                                                  1. 28

                                                    I point them to the Holocaust in the Netherlands. The Netherlands had one of the hardest-hit populations of Jews in all of Europe. There were several contributing factors, but one of them was the well-organized trove of data the government collected on all Dutch citizens including information on religion, residence, work, and ancestry. That trove of data was helpful for the smooth functioning of the Dutch government and originally employed for the good of its people. However it was also a very great help to those who later sought to oppress and exterminate.

                                                    Data is powerful. And it changes hands easily. Even if you were giving data to good people who have nothing but good intentions, you still have to be careful with it. But most of us are giving data away to people who are making money off of us. Just as you wouldn’t give your house key to a stranger who wants to exploit you for money, so you also shouldn’t give your data to someone who wants to exploit you for money.

                                                    1. 6

                                                      I just wanted to make the same point here but I see you’ve already covered it.

                                                      I come from a part of Europe that has had totalitarian regimes ruling over it in the past. Even though I haven’t lived during those regimes (missed it by a couple of years) I could definitely feel the consequences, physical or mental for a lot of people.

                                                      You could easily be detained or even killed depending on the severity of the charge. The things that could serve as proofs were telephone calls, anything you ever publicly wrote, even the private correspondence by mail. Anything you ever said in public, sometimes only the accusation of saying something would be enough.

                                                      Nowadays all of that seems trivial, the presence of the surveillance is orders of magnitude higher today than at any point in history. Imagine going to jail because you sent a joke to your friend on Whatsapp about a political figure in your country. Heck, any information that’s not perfectly protected by end to end encryption may as well be considered public. See what hackers do with stolen credit cards today, they use them for some time, then they dump them for everybody else to use.

                                                      1. 5

                                                        That is a good point. Often it is not even the own government that acts malicious. There have been recent discussion in Germany to install cameras with face detection in all airports and train stations. Our current government might not misuse these cameras. However, we should always assume the other governments hack into the cameras and use the material to track dissidents.

                                                      1. 1

                                                        If you are interested in enterprise iPaaS take a look at tray.io. We are hiring!

                                                        1. 5

                                                          Plot twist: Zoom in and see Earth and other planets.

                                                          1. 1

                                                            Haha I was imagining doing this analysis and finding a hidden message from God embedded in the numbers.

                                                          1. 4

                                                            I’m Stjepan and I tend to write about React, NodeJS and JS in general. I am planning to broaden the topics a little bit by writing about Go, cloud native development, AI, etc.

                                                            Link: https://medium.com/@stjepan.golemac Feed: https://medium.com/feed/@stjepan.golemac