[HN Gopher] Let's write a video game from scratch like it's 1987
___________________________________________________________________
Let's write a video game from scratch like it's 1987
Author : LorenDB
Score : 112 points
Date : 2024-06-20 11:21 UTC (11 hours ago)
(HTM) web link (gaultier.github.io)
(TXT) w3m dump (gaultier.github.io)
| ferrantim wrote:
| Different topic but this article got me lost down a rabbit hole
| looking for something similar for the TI86. Ah, memories...
| Sohcahtoa82 wrote:
| My favorite TI graphing calculator story to tell was back in
| Algebra II class in high school, while studying polynomial
| expansion, I wrote a program on my TI-85 that would not only
| solve them, _but also showed the work_ , so I literally only
| had to copy the exact output of the program and it looked
| exactly like I had done it by hand. I asked the teacher if
| using it would be cheating, and she said "If you know the
| material so well that you can write a program that actually
| shows the work, then you're going to ace the test anyway, so go
| ahead and use it, just don't share it with any of your
| friends."
|
| The joke was on her, of course, because I didn't have any
| friends. :-(
|
| Later I wrote a basic ray tracer for my TI-89. I even made it
| do 4x anti-aliasing by rendering the scene 4 times with the
| camera angle slightly moved and had a program that would
| rapidly move between the 4 rendered pics so that pixels that
| were dark for only some of the pictures would appear grey
| because of the screen's insanely slow response time. A basic
| "reflective sphere over a checkered plane" in that super low
| TI-89 resolution still took like 90 minutes and drained half
| the battery.
| nsguy wrote:
| I was just listening to this podcast the other day:
| https://99percentinvisible.org/episode/empire-of-the-sum/
|
| It tells the story of how TI got into the calculator market
| and the domination it achieved in the US classrooms (+ other
| interesting tidbits).
| musha68k wrote:
| Great "old-school" article! Intrigued to try Odin sometime.
|
| > One interesting thing: in Odin, similarly to Zig, allocators
| are passed to functions wishing to allocate memory. Contrary to
| Zig though, Odin has a mechanism to make that less tedious (and
| more implicit as a result) by essentially passing the allocator
| as the last function argument which is optional.
| wredue wrote:
| One of zigs core tenets is "no hidden allocations". You'll
| never see zig language supporting a default value for allocator
| parameters to support hiding it at first glance.
|
| Zig does have support for empowering library users to push
| coded settings in to libraries, and you could conceivably use
| this for writing this type of code. Although it's probably not
| worthwhile.
|
| Or you can just straight up default your library to using a
| specific allocator, fuck the calling code.
|
| Anyway. Zig has patterns to do stuff like this, but it's
| probably unwieldy in large projects and you're better off just
| making it a parameter.
|
| You can also look in to the std ArrayList, which provides
| managed and unmanaged variants for yet another way that you
| might write code that empowers users to set an allocator once,
| or set it every time.
| bsder wrote:
| The problem with "implicit allocation" is always
| multithreading.
|
| An allocation library cannot serve two masters. Maximizing
| single thread performance is anathema to multithreaded
| performance.
|
| I'd go further. If allocators don't matter, why are you using a
| systems programming language in the first place?
| deaddodo wrote:
| I will say, while this is interesting and fun to see, using a
| trivial library like SDL adds almost nothing to the overhead and
| expands support to non *nix OSes.
|
| There is definitely something to be said of bloat but probably
| not in this case. You could even keep supporting Linux versions
| as old as this promises by using legacy 1.x SDL.
| jandrese wrote:
| "adds almost nothing to the overhead" is not always true. In
| the example code in the article he kept the pixbuf in the local
| X Server memory for low overhead and fast performance over the
| network. SDL always wants to send the pixmaps over the network.
| This is not a big deal for Minesweeper, but can be tough for
| action games.
| deaddodo wrote:
| You're just outlining a major flaw in the X Server protocol,
| not SDL. That's a unique situation to that specific system
| due to it's intrinsic network-oriented design and
| specifically the issue Wayland was designed to handle, which
| doesn't have this issue.
|
| In addition, there are solutions for cache locality of the
| pixbuf for SDL that you can code around, if you specifically
| need higher performance X11 code on Linux.
| jandrese wrote:
| The article just described how he was able to avoid this
| flaw in X11 by being mildly careful in how he structured
| his code. Making sure to do the bitmap copy only once and
| then issuing copyrect() calls to the server to have it do
| all of the blitting locally. With SDL it generally wants to
| do all of the blitting on the client and then push the
| whole window over as a giant pixmap for every frame. At
| least that's what it has done when I've tried to use it.
| immibis wrote:
| It's debatably even a flaw. Network transparency is
| pretty cool. This Minesweeper probably runs faster over
| an internet SSH tunnel to Australia than _any_ pixel-
| based remote desktop protocol.
|
| You feel it's a flaw because you only ever run
| applications locally. But more constraints are a side
| effect of more possibilities, because you have to program
| the lowest common denominator of all possible scenarios,
| so your program works in all of them.
|
| That's how APIs work. They all have this tradeoff.
| caseyy wrote:
| That code is a bit too readable for that time period in games,
| hehe. See Doom:
|
| https://github.com/id-Software/DOOM/blob/master/linuxdoom-1....
| metadat wrote:
| This source code looks perfectly legible to me. In fact, for C,
| it's the equivalent of T-Ball.
|
| Nicely and consistently formatted, relevant comments, sane
| structure, along with decent fn, and var names.
|
| What is your definition of "good, readable code?"
|
| P.s. I've emailed the mods, but a currently dead child comment
| from a new account states essentially the same thing (my vouch
| was insufficient to rez):
| https://news.ycombinator.com/item?id=40742493
| LorenDB wrote:
| Look at the R_MapPlane function. Indentation in if statements
| is non-existent.
| metadat wrote:
| What? What's a pretty severe nit pick. Especially for 30
| year old C code.
|
| They didn't have no gofmt back then. We are spoiled today
| with the extreme consistency :) the skill of reading code
| includes reading even when it deviates from one's own
| preferred formatting (within reason, maliciously formatted
| code can be challenging, to say the least).
|
| I must respectfully disagree about this being an issue
| worthy of anyone's attention, especially yours and mine.
| caseyy wrote:
| I must admit, despite programming games for a long time
| commercially, that code is not clear to me.
|
| If the code is readable to you, can you explain how
| R_DrawPlanes draws the ceiling and the floor, step by step,
| as a practical illustration? If it is perfectly legible to
| you, it shouldn't take more than a minute.
|
| I think just about every function I read every day is easier
| to comprehend. And I review a lot of game engine code. I make
| no claims I'm a fantastic programmer, of course.
| LorenDB wrote:
| Man, that could use a healthy dose of clang-format.
| wslh wrote:
| I Remember that around 1985 was more simple to write basic games
| in the TI99/4A in TI Extended BASIC or Logo. The sprite support
| was an advantage from writing basic games on PCs without sprites
| support. I remember a performance similar to the Atari 2600 and
| not using Assembler.
| Jare wrote:
| I have an actual commercial game from 1987 :)
| https://github.com/TheJare/stardust-48k
| pan69 wrote:
| Actual? Is this not reversed engineered?
| MrLeap wrote:
| I think the "actual" in this case points to "commercial
| game".
| axus wrote:
| From the README.md: "Also thank to Roberto Carlos
| Fernandez, who many years ago made me promise I'd give him
| a printed copy of the sources. That copy is buried in some
| box in storage somewhere, and we'd rather do this than go
| search for it."
| Jare wrote:
| We lost the source code in any usable form. Even if we dug up
| the printed copy, scanning it would be tedious as hell. :) So
| we ended up reverse engineering our own game, fun times.
|
| But yeah, "actual" in that it's a real commercial game (30k
| copies or so) developed and released in 1987. If memory
| serves right, we started in late autumn'86 and it was
| published around November'87.
| 0xf00ff00f wrote:
| Wow, that's pretty cool. The game looks great!
|
| Was it developed on an actual ZX Spectrum? I think I read that
| the development environment for the Spectrum port of R-Type was
| running on a 80286 PC, curious if this was common back in the
| day.
| Razengan wrote:
| Even some games from 1984 or even earlier are amazingly complex,
| making you wonder how they made them in such short time with
| limited tools and manpower.
| space_oddity wrote:
| The complexity and creativity of early video games from the
| 1980s and even earlier are truly impressive
| Razengan wrote:
| And little prior art to draw inspiration from!
|
| The 1980-2000 era was just a raw font of imagination for video
| games. Since then things have become more iterative and tend to
| focus on maximizing profits, though thankfully there is a lot
| of creativity in indie studios/solo devs being empowered by the
| increasing ease of modern game engines, and even some bigger
| studios here and there, like FromSoftware.
| ilrwbwrkhv wrote:
| Passion + skill > Total compensation optimization + Javascript.
| spacecadet wrote:
| I did this last year, built a zero player pixellated space
| simulator using pygame.
| jandrese wrote:
| > X11 is old and crufty, but also gets out of the way. Once a few
| utility functions to open the window, receive events, etc have
| been implemented, it can be forgotten and we can focus all our
| attention on the game. That's very valuable. How many libraries,
| frameworks and development environments can say the same?
|
| This is my thought as well. You can even avoid some of the grotty
| details of this article if you use Xlib as your interface instead
| of going in raw over a socket. Basic Xlib is surprisingly nice to
| work with, albeit with the caveat that you're managing every
| single pixel on the screen. For something like a game where
| you're not using system widgets it is all you need.
|
| Where people ran into trouble is when they try to add the X
| Toolkit, which is far more opinionated and intrusive.
| immibis wrote:
| You might also consider using xcb, which is more of a simple
| wrapper around the X11 binary protocol, rather than Xlib which
| leakily tries to abstract it. The famous example (noted in
| XCB's documentation) is calling XInternAtom in a loop to intern
| many atoms. Xlib forces you to send request, wait for response,
| send request, wait for response. XCB lets you send all the
| requests, then wait for all the responses.
| agumonkey wrote:
| I'm often curious about how people organized / conceptualized
| development in the 60s, 70s and 80s.
| pan69 wrote:
| Writing a game, or any software in 1987 would be painstaking
| compared to the luxury we have today. Back then it was normal to
| run DOS and DOS can only do one thing at the time. You open your
| editor, write code, close your editor, run the compiler, run your
| program, test your program, exit program, re-launch editor, etc.
| Over time small improvements where made to this flow like a DOS
| Shell and even things like DESQView that allow for basic
| multitasking.
|
| This is probably a better description (from a code point of view)
| on what you had to do as a programmer to write a game in the late
| 80s / early 90s:
|
| https://cosmodoc.org/
| bsder wrote:
| Erm, there was a reason why Turbo Pascal (and the other Borland
| stuff) was such a _big deal_.
|
| And that dates to 1983.
| switchbak wrote:
| TP was just so awesome, it was like a superpower compared to
| others waiting 10-20x as long for each build.
|
| For me the big thing was all the latencies stacked together.
| Slow hard drives, slow floppies, god help you if you swapped,
| etc. The era was mostly waiting around for the beige machine
| to finally do its thing.
| toast0 wrote:
| Thank goodness for modernity. Now we wait for white, black,
| or unpainted aluminum machines to finally do their thing.
| Sometimes, we never even get to see the machines. :(
| ceronman wrote:
| > The result is a ~300 KiB statically linked executable, that
| requires no libraries, and uses a constant ~1 MiB of resident
| heap memory (allocated at the start, to hold the assets). That's
| roughly a thousand times smaller in size than Microsoft's. And it
| only is a few hundred lines of code.
|
| And even with this impressive reduction in resource usage, it's
| actually huge for 1987! A PC of that age probably had 1 or 2 MB
| of RAM. The Super NES from 1990 only had 128Kb of RAM. Super
| Mario Word is only 512KB.
|
| A PlayStation from 1994 had only 2MB of system RAM. And you had
| games like Metal Gear Solid or Silent Hill.
| switchbak wrote:
| In 1987, I think you'd be very lucky to have that much RAM. 4MB
| and higher only started becoming standard as people ran Windows
| more - so Win 3.1 and beyond, and that was only released in
| 1992.
| Doctor_Fegg wrote:
| Yes. I wrote a version of Minesweeper for the Amstrad CPC, a
| home computer popular in 1987 (though I wrote it a few years
| later). I think it was about 5-10Kb in size, not 300. The CPC
| only had 64k of memory anyway, though a 128k model was
| available.
| immibis wrote:
| It's noteworthy that it's impossible, by design, to write a
| statically linked Wayland executable. You have to load graphics
| drivers, because there's no way to just send either pixel data or
| drawing commands to the display server, like you can in X11. You
| have to put the pixel data in a GPU buffer using a GPU driver,
| then send the GPU buffer reference.
| fallingsquirrel wrote:
| Not true. Here's how to send pixel data: https://wayland-
| book.com/surfaces/shared-memory.html
___________________________________________________________________
(page generated 2024-06-20 23:00 UTC)