5 ms·
Writing a Minecraft server from scratch in Bash (2022)
- pvg 3y agoDiscussion at the time https://news.ycombinator.com/item?id=30347501 https://news.ycombinator.com/item?id=30347501 92 comments
- dang 3y agoThanks! Macroexpanded: My thoughts on writing a Minecraft server from scratch in Bash - https://news.ycombinator.com/item?id=30347501 https://news.ycombinator.com/item?id=30347501 - Feb 2022 (90 comments)
- dinkleberg 3y agoNow this is a proper hacker site. This is great.
- lanthade 3y ago[flagged]
- love2read 3y agoThis website is the one of the rare times where safari’s reader mode that changes the font was super nice to read.
- monitron 3y agoThere is a set of radio buttons in the top right corner you can use to choose a different one :)
- lagniappe 3y agoWeird, the older I get the better that font is for me. I wonder if that's because of nostalgia as all of the terminals at that age looked like this.
- unnouinceput 3y agoYou can always use reader mode of your browser.
- lanthade 3y ago100% right. I completely forgot about that. Thanks.
- TeaVMFan 3y agoAs someone who's done a lot of work with scriptable Minecraft servers for both Java and Bedrock (ScraM), this is impressive. Bonus points for using "duckduckgoing" in a sentence.
- deleted 3y ago[deleted]
- SunlitCat 3y agoJust wondering, but is writing custom servers for commercial games still a thing?
- petee 3y agoI think it will always be a thing for those who play games & like to dabble with tech, either to fix a bug, learn a language, or just see how the sausage is made.
- madeofpalk 3y agoFor Minecraft, very much so. Minecraft, especially the Java version, is in a comparatively odd place in that it receives significant free content updates AND officially supports running any historical version AND has an extremely vibrant modding community. Minecraft (Java) is as much of a game engine for others to build on as it is a game itself.
- Filligree 3y agoThe four great game engines: Unreal, Unity, Minecraft and Godot. I don’t think Minecraft is number four on the list. It might be number two.
- 3y ago
- BearOso 3y agoA negative power, i.e. 2^(-n) is just 1/(2^n). I'm surprised the author didn't remember that with their own 2^-1 = 0.5 example and eventually reached out to awk for it.
- tryauuum 3y agoI don't understand how this would help the author. Since the bash doesn't support floating point numbers anyway
- anthk 3y agoThis. Also, gawk has netwoki support, so you can write an mc server with just gawk.
- BearOso 3y agoI had the same thought. bc would have been a lighter choice. And tryauuum, I think the author only needed powers of two to emulate floating point in the first place. So they could just divide said number by 2 a number of times.
- taviso 3y agoThey should have used my (dumb?) library, ctypes.sh: https://github.com/taviso/ctypes.sh https://github.com/taviso/ctypes.sh Then they can access libm, poll(), select() and so on from bash :)
- lagniappe 3y agowoah that's cool :) also hello tavis
- MrBuddyCasino 3y agoI‘m not sure you should have done that, but it is impressive for the sheer chuzpa of it. Like reanimating Frankenstein.
- jethro_tell 3y agoLol, holy shit what did I just read? Amazing, installing now. I want to be part of the problem.
- Brian_K_White 3y agoAwesome, but beside the point of writing something in bash that never needed to be in bash for any technical reason. Meaning if it requires bash plus some specially installed compiled c code, then it might as well require c or python or anything else and there is no point in calling it "written in bash", or writing it in mostly-bash-plus-special-plugin. I do know who I'm speaking to so please assume I say this respectfully. :) I have no problem with a "pointless" project like that as I'll show in a second. That said, this minecraft project itself relies on externals like xxd when it doesn't need to, so using ctypes.sh would be no worse in this case, so you are right, in this case they might as well have. But for the record it is possible to read, store, manipulate, do math on, and output binary in pure bash without anything like dd or xxd. The only byte that is a problem is null, and there is a way to deal with that. You can't directly store a null, but you can detect that you read one and store that info, and reconstruct it on output later, or do math on it, use it's numerical value as an array index or byte offset or whatever the byte is for. For a minimal example, just copying a binary file: while LANG=C IFS= read -d '' -r -n 1 x ;do printf '%c' "$x" ;done <bin1 >bin2 That's a bit too minimal since it doesn't show what other kinds of things you can do that are more useful than cat-without-cat. A bit more generic and useful: https://gist.github.com/bkw777/c1413d0e3de6c54524ddae890fe8d705 https://gist.github.com/bkw777/c1413d0e3de6c54524ddae890fe8d... The LANG=C, IFS= , and -d'' all combine to render all bytes accessible except 0x00, and then the return value from read() tells you the difference between "we read a 0x00" and "we didn't read anything" and "input ended" And it doesn't have to use < and > on the overall while() comand either. You can exec 3<>file_or_fifo_or_tty and read -u3 / printf >&3 etc inside the loop instead. An example reading from a serial port: https://gist.github.com/bkw777/ddde771cc85fdd888c7ec74953193d66 https://gist.github.com/bkw777/ddde771cc85fdd888c7ec74953193... Used in anger: https://github.com/bkw777/pdd.sh https://github.com/bkw777/pdd.sh see tpdd_read, tpdd_write, file_to_fhex, str_to_shex reading and writing both a serial port and local files and doing all kinds of processing on the data. And these loops are not even subshells let alone externals. You can manipulate variables inside the loop and you are still in the same original context. I'd say parent shell but there are no childern. Those all read a single byte at a time with read -n 1, but they don't have to. You can read without the -n1 and each iteration of the loop will collect as much as it can between nulls instead of always one byte. That would consume less ram and less loop iterations. But the things I'm using them for want to slice & dice the individual bytes and byte-ranges at numerical offsets anyway and the data is always small (by todays standards) so the array-of-hex-pairs is just too convenient where a[n] == byte n, and all bytes are treated the same whether printable, non-printable, or null, and aside from merely storing and regenerating the bytes with printf you can also use the numerical values directly as well by simply prepending 0x, so 0x$n or 0x${a[n]} almost anywhere you would normally have a simple integer. So you can do math on them and use them as array indexes and byte offsets etc. Read the 2nd byte of h[] as a length of the payload to follow, and clip out that payload: ${h[@]:2:0x${h[1]}}
- bilekas 3y agoSo that happened... Jesus. I've read a lot of articles about the way they implement stuff but this takes the cake. Hands down one of, if not the best write up of something wild I've ever read. Top shelf.
- osigurdson 3y agoWhile I am not good at bash programming, I am surprised how capable / non horrible it actually is.
- fddrdplktrew 3y agoMinecraft, one of greatest game since Quake
- okcdz 3y ago[flagged]
- synergy20 3y agobash is one of my favorite, as favorite as vim and lua. a single binary that is less than 2M bytes, universal, way more capable than many people think. with shellcheck and good habits, bash can be readable and safe as well. if you want something extra, you can always use C/C++ to add those utilities without using more involved FFI etc, and without pip/npm/etc to load who knows how many dependencies.
- inetknght 3y ago> with shellcheck and good habits, bash can be readable and safe as well. My favorite thing to do with shellcheck: add it to CI. Developers hate this one trick! A lot of times CI and Dockerfiles have inline bash scripts. My next favorite thing to do is to move all of that inlined bash to their own script files. Now that CI has shellcheck: all that stuff gets checked too! Developers seem to hate this though because it's "less readable". Less readable my ass, it's way more safe. Next problem: the same bash scripts are now in the same files in multiple repositories (a distributed build). I'm open to ideas for improvements here.
- klardotsh 3y agoTo skip the "move your scripts to standalone files" step some devs don't like, consider something like https://github.com/hadolint/hadolint https://github.com/hadolint/hadolint which runs Shellcheck over inline scripts within Containerfiles.
- yodsanklai 3y agoI dislike bash because I'm not good with it. It sucks but is still often the best solution available. Actually, one of my regret was not to invest more time on it when I was a student (a while ago) because it's one of these rare tools that accompanied me my whole career.
- inetknght 3y agoIt's true. The nice thing is that there are many many examples of how to use bash. Just open a script file in random repositories. Most scripts are super SUPER simple. But just copy-paste to shellcheck and it will give some feedback if you're looking to get in some really quick commits and PRs :)