[HN Gopher] Writing a Minecraft server from scratch in Bash (2022)
___________________________________________________________________
Writing a Minecraft server from scratch in Bash (2022)
Author : LorenDB
Score : 317 points
Date : 2024-03-02 14:42 UTC (1 days ago)
(HTM) web link (sdomi.pl)
(TXT) w3m dump (sdomi.pl)
| pvg wrote:
| Discussion at the time
| https://news.ycombinator.com/item?id=30347501 92 comments
| dang wrote:
| Thanks! Macroexpanded:
|
| _My thoughts on writing a Minecraft server from scratch in
| Bash_ - https://news.ycombinator.com/item?id=30347501 - Feb
| 2022 (90 comments)
| dinkleberg wrote:
| Now this is a proper hacker site. This is great.
| TeaVMFan wrote:
| As 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.
| SunlitCat wrote:
| Just wondering, but is writing custom servers for commercial
| games still a thing?
| petee wrote:
| I 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 wrote:
| For 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 wrote:
| The 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.
| jasonjayr wrote:
| Roblox is somewhere on that list too ....
| Filligree wrote:
| How many thousand mods does it have?
| BalinKing wrote:
| Isn't each server its own mod, in effect?
| themoonisachees wrote:
| This is because in addition to being the most sold video game
| of all time, minecraft is effectively open source. It's not
| literally open source, but you can decompile java bytecode
| with standard tooling, and symbols are available, either
| community-reversed, or official.
| teaearlgraycold wrote:
| Frustrating how game studios can see Minecraft's success
| here and not change a thing about their development
| practices.
| Aurornis wrote:
| There's actually a very large and vibrant community for
| modding Unity games like this.
|
| More competitive games can't afford any type of easy
| reverse engineering due to the cheating factor.
| darknavi wrote:
| Mods are the (amazing) end game for Lethal Company. So
| many fun, new tweaks and content.
| noah91734 wrote:
| For the curious: https://thunderstore.io/c/lethal-
| company/
|
| Click on any mod, and you can see the decompiled source.
| The mods use function hooking to run before or after
| certain functions are called rather than the event based
| system you see in Minecraft plugins.
| ryukoposting wrote:
| I think Minecraft's position today has as much to do with
| the content of the game itself as it has to do with its
| architecture/Mojang's engineering choices.
|
| The nearly-infinite expandability and modularity of
| Minecraft is partially due to the simplicity of the art,
| core game mechanics, and lack of storyline. Good mods are
| harder to make when the world they must integrate into is
| more complex.
|
| I think this means a lot of games wouldn't see the kind
| of sustained success Minecraft has seen, even with more
| "open" development practices.
|
| I hypothesize that the "open world" craze of years past
| was an attempt to capture Minecraft magic, but those
| games lacked the _thematic_ open-endedness that really
| facilitates Minecraft 's longevity.
| LtWorf wrote:
| minetest is open source for real though
| LtWorf wrote:
| Minetest is much more of a game engine.
|
| I've heard from someone I know that played both extensively
| that minetest is less prone to losing everything for data
| corruption (never happened once in minetest, regularly in
| minecraft after a while. But sample size is 1).
| tehbeard wrote:
| Is that sample size of one from the java edition or bedrock
| edition of minecraft?
| LtWorf wrote:
| java
| chungy wrote:
| I don't think I've ever witnessed data corruption in
| Minecraft, and that's even playing since Alpha 1.0.11 and
| multiple data format migrations... well, my sample size is
| 1, too.
|
| I've also been on ZFS nearly the whole time. Are you
| certain Minecraft actually corrupted your data file, or do
| you suffer underlying hardware failure?
| firtoz wrote:
| AFAIK yes, the RE scene is still active.
| haunter wrote:
| Not just servers but for some games clients too
| https://runelite.net/
| static_motion wrote:
| I find RuneLite a fascinatingly well-built piece of software.
| The lead dev, Adam, did a fantastic job with it, and good on
| Jagex for allowing its use, even as far as advertising it on
| their own front page.
| hoten wrote:
| It really papers over (some of) the tedium of the game and
| let's you enjoy the rest easier. Love it.
| SunlitCat wrote:
| Although writing game servers for commercial games is already
| "difficult", isn't writing game clients for commercial games
| a huge issue copyright wise?
| BearOso wrote:
| A 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 wrote:
| I don't understand how this would help the author. Since the
| bash doesn't support floating point numbers anyway
| anthk wrote:
| This. Also, gawk has netwoki support, so you can write an mc
| server with just gawk.
| BearOso wrote:
| I 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 wrote:
| They should have used my (dumb?) library, ctypes.sh:
|
| https://github.com/taviso/ctypes.sh
|
| Then they can access libm, poll(), select() and so on from bash
| :)
| lagniappe wrote:
| woah that's cool :) also hello tavis
| MrBuddyCasino wrote:
| I'm not sure you should have done that, but it is impressive
| for the sheer chuzpa of it. Like reanimating Frankenstein.
| jethro_tell wrote:
| Lol, holy shit what did I just read?
|
| Amazing, installing now. I want to be part of the problem.
| Brian_K_White wrote:
| Awesome, 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/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/ddde771cc85fdd888c7ec74953193...
|
| Used in anger: 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]}}
| captainbland wrote:
| I mean if it's good enough for python...
| synergy20 wrote:
| would love to see how poll() and select() etc work this way
| taviso wrote:
| Here are some examples!
|
| https://github.com/taviso/ctypes.sh/blob/master/test/select..
| ..
| https://github.com/taviso/ctypes.sh/blob/master/test/poll.sh
|
| Yes, it is crazy :)
| bilekas wrote:
| So 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 wrote:
| While I am not good at bash programming, I am surprised how
| capable / non horrible it actually is.
| fddrdplktrew wrote:
| Minecraft, one of greatest game since Quake
| synergy20 wrote:
| bash 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 wrote:
| > _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.
| yodsanklai wrote:
| I 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 wrote:
| It'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 :)
___________________________________________________________________
(page generated 2024-03-03 23:01 UTC)