Most active commenters
  • db48x(9)
  • (7)
  • trinix912(6)
  • Henchman21(4)
  • RHSeeger(4)
  • mrguyorama(3)

←back to thread

1371 points yett | 77 comments | | HN request time: 2.322s | source | bottom
1. db48x ◴[] No.43772686[source]
[flagged]
replies(8): >>43772700 #>>43772801 #>>43772908 #>>43773054 #>>43773261 #>>43774132 #>>43774982 #>>43777757 #
2. ◴[] No.43772700[source]
3. mschuster91 ◴[] No.43772801[source]
To u/db48x whose post got flagged and doesn't reappear despite me vouching for it as I think they have a point (at least for modern games): GTA San Andreas was released in 2004. Back then, YAML was in its infancy (2001) and JSON was only standardized informally in 2006, and XML wasn't something widely used outside of the Java world.

On top of that, the hardware requirements (256MB of system RAM, and the PlayStation 2 only had 32MB) made it enough of a challenge to get the game running at all. Throwing in a heavyweight parsing library for either of these three languages was out of the question.

replies(11): >>43772845 #>>43772895 #>>43773040 #>>43773086 #>>43773123 #>>43773186 #>>43773306 #>>43773332 #>>43773461 #>>43774704 #>>43775548 #
4. ceejayoz ◴[] No.43772845[source]
Vouching seems to be time-lagged and require more than one.
5. Magma7404 ◴[] No.43772895[source]
The comment reappeared, and while you're right about using proper libraries to handle data, it doesn't excuse the "undefined behavior (uninitialized local variables)" that I still see all the time despite all the warning and error flags that can be fed to the compiler.

Most of the time, the programmers who do this do not follow the simple rule that Stroustrup said which is to define or initialize a variable where you declare it (i.e. declare it before using it), and which would solve a lot of bugs in C++.

replies(3): >>43773025 #>>43773146 #>>43773364 #
6. delfaras ◴[] No.43772908[source]
funnily enough, there was an infamous bug in GTA5 for a long time that was related to using JSON : https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...
replies(2): >>43772956 #>>43773231 #
7. Henchman21 ◴[] No.43772956[source]
Loading times are still absurd, fwiw.
replies(1): >>43773287 #
8. mschuster91 ◴[] No.43773025{3}[source]
> it doesn't excuse the "undefined behavior (uninitialized local variables)" that I still see all the time despite all the warning and error flags that you can feed to the compiler.

Yeah but we're talking about a 2004 game that was pretty rushed after 2002's Vice City (and I wouldn't be surprised if the bug in the ingestion code didn't exist there as well, just wasn't triggered due to the lack of planes except that darn RC Chopper and RC plane from that bombing run mission). Back then, the tooling to spot UB and code smell didn't even exist or, if at all, it was very rudimentary, or the warnings that did come up were just ignored because everything seemed to work.

9. ◴[] No.43773040[source]
10. ◴[] No.43773054[source]
11. ◴[] No.43773086[source]
12. kevin_thibedeau ◴[] No.43773123[source]
The flaw isn't the language. The issue is a 0.5x programmer not knowing to avoid sscanf() and failing to default and validate the results. This could be handled competently with strtok() parsing the lines without needing a more complicated file format.
replies(2): >>43773433 #>>43773984 #
13. Yeask ◴[] No.43773146{3}[source]
And it did not matter at all. The game shipped and was a success.
replies(2): >>43773286 #>>43774700 #
14. bluedino ◴[] No.43773186[source]
Why weren't binary files used like I would expect in the 1990's DOS game? fread into a struct and all that
replies(3): >>43773266 #>>43773852 #>>43773954 #
15. db48x ◴[] No.43773231[source]
I remember that one too :)

They wrote a JSON “parser” using sscanf. sscanf is not bulletproof! Just use an open source library instead of writing something yourself. You will still be a real programmer, but you will finish your game sooner and you won't have embarrassing stories written about you.

16. trinix912 ◴[] No.43773261[source]
Putting the (very valid) reasons for not having human-readable game saves aside, are you sure it's worse than using a 3rd party library that's built to accept semi-valid input values, possibly evaluates user input in some way and has difficult to debug bugs that occur only under certain inputs? I agree that writing a stable and safe parser for a binary data file isn't easy, but there's less things that can go wrong when you can hardcode it to reject any remotely suspicious input. Third party XML/JSON libraries OTOH try to interpret as much as possible, even when the values are bogus. Also no need to deal with different text encoding bugs, line endings...
replies(2): >>43773307 #>>43773413 #
17. epcoa ◴[] No.43773266{3}[source]
By the 2000s, portability was a concern for most titles. Certainly anything targeted at a rapidly changing console market back then.
replies(1): >>43773793 #
18. ryandrake ◴[] No.43773286{4}[source]
This is the thing that drives artists and craftsmen to despair and drink: That a flawed, buggy, poor quality work can be "successful" while something beautiful and technically perfect can fail.
replies(4): >>43773416 #>>43773459 #>>43773594 #>>43776294 #
19. hnuser123456 ◴[] No.43773287{3}[source]
Yes, but now it's in the realm of ~3 minutes, and not ~8 minutes even on a top-spec PC, right? I really liked the game, but waiting 8 minutes to load just to get griefed by hackers within seconds of walking outside... I don't understand how that game makes any money.
replies(2): >>43773326 #>>43774074 #
20. db48x ◴[] No.43773306[source]
You’re not entirely wrong, but a library doesn’t have to be “heavyweight” in order to be bulletproof. And you can load the library during startup and then unload it after; it doesn’t have to stick around for the whole run time of the game. Modern OSes will reclaim the pages after you stop using them, if there is memory pressure. Of course the PS2 didn’t do that I am sure.
replies(1): >>43773412 #
21. hattar ◴[] No.43773307[source]
> Putting the (very valid) reasons for not having human-readable game saves aside,

I don't follow. What would the reasons be?

replies(4): >>43773397 #>>43773436 #>>43773439 #>>43773462 #
22. db48x ◴[] No.43773326{4}[source]
It was like crack. People put up with a lot of problems and bugs just because it was really fun just enough of the time to get them hooked.
replies(2): >>43774473 #>>43774489 #
23. anthk ◴[] No.43773332[source]
XML was everywhere.
24. trinix912 ◴[] No.43773364{3}[source]
While it doesn't excuse the bad habits, we do have to keep in mind C++98 (or whatever more ancient was used back then) didn't have the simple initializers we now take for granted. You couldn't just do 'Type myStruct = {};' to null-initialize it, you had to manually NULL all nested fields. God forbid you change the order of the variables in the struct if you're nesting them and forget to update it everywhere. It was just considerably more practical to do 'Type myStruct;' then set the fields when needed.
replies(2): >>43773458 #>>43775233 #
25. gsinclair ◴[] No.43773397{3}[source]
A human-readable game save file is presumably human-editable.
replies(3): >>43773604 #>>43773642 #>>43773899 #
26. rfoo ◴[] No.43773412{3}[source]
Meanwhile, in a certain modern OS, unloading a library is too broken to the point that people are discouraged to do so... Try to unload GLib [0] from your process :p

[0] https://docs.gtk.org/glib/

replies(1): >>43775486 #
27. db48x ◴[] No.43773413[source]
You misunderstood. Game developers should use a _good_ third–party library, not a _bad_ one. At a minimum they should be able to read the source code so that they know it is good. Thus open source libraries should be at the top of the list.

If you don't know what “good” looks like, take a look at [Serde](https://serde.rs/). It’s for Rust, but its features and overall design are something you should attempt to approach no matter what language you’re writing in.

replies(1): >>43773567 #
28. butlike ◴[] No.43773416{5}[source]
The job of the artist is to take the years of expertise and distill it down into something "enjoyable." The hardest mental hurdle to get over is that people just don't care about the technicals being perfect. Hell, the final product doesn't even need to be beautiful; it just needs to be arresting.
replies(1): >>43773603 #
29. butlike ◴[] No.43773433{3}[source]
Worked fine on the target machines and the "0.5x programmer" got to see their family for winter holiday. Or are you saying they should have defensively programmed around a bug manifesting 21 years later and skip seeing their family during crunch time?

To be honest, I just don't like how you disparaged the programmer out-of-context. Talk is cheap.

replies(1): >>43773548 #
30. trinix912 ◴[] No.43773436{3}[source]
Mostly to prevent people and programs from editing them, obfuscating implementation details, reducing file sizes (say had they used XML vs. binary)...
31. egypturnash ◴[] No.43773439{3}[source]
Higher barrier to cheating.
replies(2): >>43773498 #>>43775340 #
32. badc0ffee ◴[] No.43773458{4}[source]
You could always `bzero` or `memset` the entire struct to 0.
replies(1): >>43773484 #
33. soulofmischief ◴[] No.43773459{5}[source]
San Andreas might be rough under the hood, but on the surface it was nothing short of a masterpiece of game design. The engine was so complex and the cities felt alive, and the game could handle a lot of general nonsense. Still one of my favorite go-to games.
34. ◴[] No.43773461[source]
35. ◴[] No.43773462{3}[source]
36. trinix912 ◴[] No.43773484{5}[source]
But only if it contains strictly POD members, otherwise it's UB.
37. hattar ◴[] No.43773498{4}[source]
It's a single player game. Cheat codes are built into it by design.
38. db48x ◴[] No.43773548{4}[source]
Using a well–written third–party library would not increase the development time; it would in fact reduce it. No risk of missing Christmas there.
replies(1): >>43773635 #
39. vinyl7 ◴[] No.43773567{3}[source]
There are no good third party libraries
replies(1): >>43773702 #
40. RHSeeger ◴[] No.43773594{5}[source]
One artist can take months painting a picture of a landscape where everything is perfect. And the next artist can throw 4 colors of paint at a wall. The fact that lots of people enjoy the work of the second artist doesn't invalidate the work of the first. The two artists are focusing on different things; and it's possible for both of them to be successful at reaching their goals.
41. RHSeeger ◴[] No.43773603{6}[source]
Heck, sometimes the thing that's most interesting about a work is people arguing over whether or not it's art.
42. kadoban ◴[] No.43773604{4}[source]
Require a hash in the file to match the rest of the file if you want to avoid effortless changes to the file.

(There is no way to prevent changes by a knowledgeable person with time or tools, so that's not a goal)

43. trinix912 ◴[] No.43773635{5}[source]
Well-written 3rd party serialization libraries weren't exactly easy to come by 20 years ago, at least from what I can recall. Your best bet was using an XML library, but XML parsing was quite resource heavy. Many that seemed well designed turned out to be a security nightmare (Java serialization).
replies(1): >>43773811 #
44. RHSeeger ◴[] No.43773642{4}[source]
Most binary save game files are human editable, too; unless they go through a separate encoding stage.
replies(1): >>43775181 #
45. db48x ◴[] No.43773702{4}[source]
I disagree. Serde is not merely good, it is excellent.

The only C code that I have recently interacted with uses a home–grown JSON “library” that is actually pretty good. In particular it produces good error messages. If it were extracted out into its own project then I would be able to recommend it as a library.

replies(1): >>43773807 #
46. coldpie ◴[] No.43773793{4}[source]
Definitely, and architectures back then were far less standardized. The Xbox 360 was a big-endian PowerPC CPU, the PS2 had a custom RISC-based CPU. On the desktop, this was still the era of PowerPC-based Macs. Far easier (and I would argue safer) to use a standard, portable sscanf-like function with some ascii text, than figure out how to bake your binaries into every memory and CPU layout combination you might care about.
47. trinix912 ◴[] No.43773807{5}[source]
But how is that C project using a custom made JSON library doing better than Rockstar games doing the same? Because that library has good error messages?

Apart from that, many of us thought that Java serialization was good if just used correctly, that IE's XML parsing capabilities were good if just used correctly, and so on. We were all very wrong. And a 3rd party library would be just some code taken from the web, or some proprietary solution where you'd once again have to trust the vendor.

replies(1): >>43773867 #
48. db48x ◴[] No.43773811{6}[source]
I disagree. JSON is 25 years old, and SAX parsers are 22. A SAX parser is the opposite of “resource heavy”, since it is event driven. The parser does not maintain complex state, although you might have to manage some state in order to correctly extract your objects from the XML. Granted, it wouldn’t have integrated nicely with C to generate the parser code from your struct definition back then, but the basics were there.

But it is even more important for today’s game studios to see and understand the mistakes that yesterday’s studios made. That’s the only way to avoid making them all over again.

replies(1): >>43775816 #
49. mrguyorama ◴[] No.43773852{3}[source]
Video games are made by a lot of non-programmers who will be much more comfortable adjusting values in a text file than they are hex editing something.

Besides, the complaint about not having a heavyweight parser here is weird. This is supposed to be "trusted data", you shouldn't have to treat the file as a threat, so a single line sscanf that's just dumping parsed csv attributes into memory is pretty great IMO.

Definitely initialize variables when it comes to C though.

50. db48x ◴[] No.43773867{6}[source]
It’s good because they have spent hundreds or thousands of hours polishing and improving it. It’s paid off too, because stable releases never have broken data files any more. Any mistakes that do get made are usually found and fixed before the code is ever committed. Even the experimental branch rarely sees broken data files. It’s more likely to see these error messages when loading save files, because the code to read old save files and convert them for newer versions of the game is the hardest to write and test.

> And a 3rd party library would be just some code taken from the web, or some proprietary solution where you'd once again have to trust the vendor.

Open source exists for a reason, and had already existed for ~15 years by the time this game was begun. 20 years later there are even fewer excuses to be stuck using some crappy code that you bought from a vendor and cannot fix.

replies(1): >>43774449 #
51. mrguyorama ◴[] No.43773899{4}[source]
Before game companies earned all their profit through selling cosmetics and premium currency nobody cared if you cheated at your single player game and nobody SHOULD care if you want to give yourself extra money.

It's only now that single player progress is profitable to sell that video games have taken save game encryption to be default.

It's so stupid.

replies(1): >>43774385 #
52. CamouflagedKiwi ◴[] No.43773954{3}[source]
Easier for internal development. Non- or less technical team members can tweak values without having to rebuild these binary files. Possibly also easier for lightweight modding externally as well.

This isn't that uncommon - look at something like Diablo 2 which has a huge amount of game data defined from text files (I think these are encoded to binary when shipped but it was clearly useful to give the game a mode where it'd load them all from text on startup).

53. danbolt ◴[] No.43773984{3}[source]
I’ll be the first to defend the greybeards I’ve befriended and learned from in AAA, but having seen codebases of that age and earlier, the “meta” around game development was different back then. I think the internet really changed things for the better.

Your average hire for the time might have been self-taught with the occasional C89 tutorial book and two years of Digipen. Today’s graduates going into games have fallen asleep to YouTube lectures of Scott Meyers and memorized all the literature on a fixed timestep.

replies(1): >>43774926 #
54. Henchman21 ◴[] No.43774074{4}[source]
IMO it varies widely. This past weekend it was taking me multiple attempts to get logged in to a public lobby— after waiting ~5-10 minutes!

Nothing has changed appreciably. If they would let you login to a private invite-only lobby that would likely speed things up greatly— but it’ll never happen.

replies(1): >>43774347 #
55. formerly_proven ◴[] No.43774347{5}[source]
That's probably just the nature of P2P networking code.

> If they would let you login to a private invite-only lobby that would likely speed things up greatly— but it’ll never happen.

Did they remove this option in the last couple years?

replies(1): >>43774462 #
56. keyringlight ◴[] No.43774385{5}[source]
The trouble is that if some weirdness happens because of the edit, you've got to handle it even if you say it would be reasonable to assume that it's outside of being supported. Maybe you spend a bit more time defensive coding around what inputs it reads from the file, maybe a certain proportion of users doing the save edit see bugs in an apparently unrelated part of the game and seek support (and their bug report might not be complete with all the details), developers spend time to chase down what went wrong, maybe they bad-mouth it on forums which affects sales - there's going to be some cost to handling all of that.

One of the anecdotes from Titan Quest developed by Iron Lore is that their copy protection had multiple checks, crackers removed the early checks to get the game running but later 'tripwires' as you progress through the game remained and the game appeared to crash. So the game earned a reputation for being buggy for something no normal user would hit running the game as intended.

replies(1): >>43774995 #
57. sumtechguy ◴[] No.43774449{7}[source]
You both are correct.

But also keep in mind in 2004 the legality of many open source projects was not really tested very well in court. Pretty sure that was right around the time one of the bigger linux distros was throwing its weight around and suing people. So you want to ship on PS2 and XBOX and PC and GameCube. Can you use that lib from inside windows? Not really. Can you build/vs buy? Buy means you need the code and probably will have to port it to PS2/GameCube yourself. Can you use that opensource lib? Probably, but legal is still dragging its feet, and you get to port it to PS2. Meanwhile your devs need a library 3 weeks ago and have hacked something together from an older codebase that your company owns and it works and means you can hit your gold master date.

Would you do that now? No. You would grab one of the multitudes of decent libs out there and make sure you are following the terms correctly. Back then? Yeah I can totally see it happening. Open source was semi legally grey/opaque to many corporations. They were scared to death of losing control of their secret sauce code and getting sued.

58. Henchman21 ◴[] No.43774462{6}[source]
I don’t think its ever been an option to login directly to an invite-only lobby. But then I have taken multiple multi-year breaks! I was pleasantly surprised you can actually play most of the game in a private lobby now… that is a huge change and I am not at all certain when it occurred.
59. Henchman21 ◴[] No.43774473{5}[source]
Definitely similar to a drug addiction, speaking from firsthand experience with both. GTA has been harder to give up than cocaine was.
60. MyPasswordSucks ◴[] No.43774489{5}[source]
Nitpicking: What you're describing is called a "variable ratio reinforcement schedule", and is considered to be the most effective form of operant conditioning.

However, it's not even remotely "like crack". Crack is really really really really fun, period, no "just enough of the time" about it. The reason people get hooked on crack is because it's guaranteed to be fun.

If I had to choose a substance that most closely mirrored variable ratio reinforcement conditioning, it'd probably be ketamine.

61. usefulcat ◴[] No.43774700{4}[source]
Let's be clear that it was a success very much in spite of UB, not because of it. And there was still a cost--likely at least hundreds of person-hours spent fixing other similar bugs due to UB (if not more).

I worked in gamedev around the time this game was made and this would have been very much an ordinary, everyday kind of bug. The only really exceptional thing about it is that it was discovered after such a long time.

replies(1): >>43776234 #
62. PhilipRoman ◴[] No.43774704[source]
Wow I had no idea YAML was that old. I always thought it was created some time around when CI/CD became popular. Now I'm really curious how it ended up as a superset of JSON.
63. fragmede ◴[] No.43774926{4}[source]
Otoh, the Internet has meant that nothing is ever finished, there's always an update to download.
replies(1): >>43775996 #
64. dogleash ◴[] No.43774982[source]
Telling a 3d engine programmer not to have opinions on data formats? Good luck with that.
65. mrguyorama ◴[] No.43774995{6}[source]
>The trouble is that if some weirdness happens because of the edit, you've got to handle it even if you say it would be reasonable to assume that it's outside of being supported.

What? No. What even are you suggesting? Hell, games with OFFICIAL MODDING SUPPORT still require you submit bug reports with no mods running.

Editing game files has always been "you are on your own", even editing standard Unreal config files is something you wont get support for, and they are trivial human readable files with well known standards.

>One of the anecdotes from Titan Quest

Any actual support for this anecdote? Lots of games have anti-piracy features that sneakily cause problems, and even could fire accidentally. None of those games get a reputation for being buggy. Games like Earthbound would make the game super hard and even delete your save game at the very end. Batman games would nerf your gliding ability. Game Dev Tycoon would kill your business due to piracy.

None of these affected the broad reputation of the game. Most of them are pretty good marketing in fact.

replies(1): >>43776548 #
66. hermitdev ◴[] No.43775181{5}[source]
Editting simcity saves was my introduction to hex editing...
replies(1): >>43784537 #
67. mrighele ◴[] No.43775233{4}[source]
I haven't been using C++ for a number of years but I think you could set the default values of fields even back then. Something like

    struct test {
        int my_int = 0;
        int* my_ptr = std::nullptr;
    };
Or is this something more recent ?

You cannot initialize them with a different value unless you also write a constructor, but it not the issue here (since you are supposed to read them from the file system)

replies(1): >>43775923 #
68. RGamma ◴[] No.43775340{4}[source]
HESOYAM
69. wat10000 ◴[] No.43775486{4}[source]
Unloading C libraries is fundamentally fraught with peril. It's incredibly difficult to ensure that no dangling pointers to the library remain when it's unloaded. It's really fun to debug, too. The code responsible for the crash literally is not present in the process at the time of the crash!
70. debugnik ◴[] No.43775548[source]
JSON didn't save them: This is the same studio that handrolled a JSON parser with accidentally quadratic time complexity, making most players wait 3 to 10 minutes to load GTA Online, for 7 years, until a player got tired and found the root cause.

https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...

71. khedoros1 ◴[] No.43775816{7}[source]
> JSON is 25 years old

And in 2004, didn't have a published specification, or much use outside of webdev (which hadn't eaten the world yet).

> and SAX parsers are 22

And, especially at the time, pretty much exclusive to Java, right?

Put another way, which are the high-quality open-source implementations of those formats that the developers should've considered while working on SA in 2003 and 2004? Or for that matter, in the 2001-2002 timeframe, when the parsing code was probably actually written for use in VC?

72. MrRadar ◴[] No.43775923{5}[source]
That's C++11 syntax. Before then you'd have to manually initialize them in every constructor, with a hand-written default constructor as a minimum:

    struct test {
        int my_int;
        int *my_ptr;
        
        test() : my_int(0), my_ptr(NULL) {}
    };
73. ◴[] No.43776234{5}[source]
74. Yeask ◴[] No.43776294{5}[source]
Some artist also think "is mot music because it has no guitars".

The standars "artist" have are atificial and snoby.

How can Deadmau5/whatever EDM artist sell so much?

75. dwattttt ◴[] No.43776548{7}[source]
Game Dev Tycoon even later added Pirate Mode to the game, for people who wanted to experience super-hard-mode. Complete with random mail they got telling them why people pirated their game, framed as why people were pirating the game you just made.
76. jhatemyjob ◴[] No.43777757[source]
After finishing the article I immediately did ctrl+f "rust" and was disappointed to not see any of the results I wanted, but actually this comment is more hilarious than anyone saying "why didnt rockstar use rust in 2004!!!1111!!???" it's a bit more of a sophisticated joke since there's an IYKYK factor but it is no less hilarious. Bravo sir, bravo.
77. RHSeeger ◴[] No.43784537{6}[source]
For me, iirc, it was Bard's Tale