522 pointsby AshleysBrain3 months ago18 comments
  • g7r2 months ago
    Ah, nice story!

    This reminds me of another story with FPU involved. I was a game developer once. We were making a game that consistently triggered assertion failures related to FPU calculations, but only on a single PC in the whole office. The game was explicitly setting FPU precision to 32 bits at the start to make all calculations more consistent. However, on that particular PC, there was a fancy hand writing input software that injected its DLL into every process. As you've probably already guessed, that DLL did FPU mode reset to the default in the event handling loop (i.e., main thread). I had to shift FPU mode setting code from process initialization to the event handling loop to be able to deal with the damage that third party DLLs could inflict.

    • djmips2 months ago
      nice detective work. Global FPU state had sure caused a lot of headaches.
      • zokier2 months ago
        I recall that D3D liked poking FPU state too, which of course had all sorts of fun results
  • stevefan19992 months ago
    Reminds me of what G-Man said in the opening scene of HL2: "The right man in the wrong place can make all the differences in the world"
    • powerclue2 months ago
      Indeed, that quote is deployed prominently in red text in the thread, in fact.
  • zX41ZdbW2 months ago
    This reminds me of an old bug in simdjson - any usage of it breaks std::unordered_map in unrelated parts of the code due to an unintentional modification of FPU flags: https://github.com/simdjson/simdjson/issues/169
    • mattgreenrocks2 months ago
      Beautiful, and by that, I mean completely and utterly horrific.
  • Wowfunhappy3 months ago
    Wait, so is that "beta" of Half Life 2 VR a thing I can play? If it is, how did I not know about this, and if not... why not?

    I'd also love to play Portal, actually. They say it makes you sick, but to my knowledge I'm immune from VR motion sickness, so worth a try...

    • Shekelphile2 months ago
      It was publicly released in 2013 and you can enable it with -vr in args IIRC. Not sure if it would work with modern VR hardware since steamvr wasn't a thing back then.
      • account422 months ago
        It did work with the Index at some point. Valve have been neglecting VR though (especially on Linux) so I wouldn't bet on it still working.
        • RobKohr2 months ago
          Considering the upcoming release of Frame, a VR headset based on Linux, I feel this couldn't be a more untrue statement.

          The real truth is they moved out of the game development space and embraced the game platform space letting their old products wither and die.

          • akimbostrawman2 months ago
            Both can be true considering they are very different projects and hardware. SteamVR on linux even with a steam index has many issues. I am sure however that the linux support of the frame will be much better considering it also releases alongside there own Linux PC.
      • Wowfunhappy2 months ago
        Ah, it predates SteamVR! Thanks, that explains why I didn't know about it.
    • aranelsurion3 months ago
      I don’t know about the beta, but there’s an excellent HL2 VR conversion mod you can play today. It feels just right and got me to play HL2 again after all these years.
      • Philpax2 months ago
        • accrual2 months ago
          Fantastic! If HL3 releases on VR, maybe I'll do HL2 in VR (refresher), then Alyx, then HL3. :)
          • phantasmish2 months ago
            HL3 exclusively in VR is likely the only thing that’d get me to increase my “time spent in VR” from the current about-ten-minutes to about six hours.
            • Agentlien2 months ago
              Interesting that Half-Life: Alyx exclusively in VR wasn't enough, then. I love VR and that game is the best VR experience I've had.
              • phantasmish2 months ago
                It’s something I keep meaning to play. My wife got a decent headset for free through work about three or four years ago, and after we both played a collective 15 minutes of Beat Saber it’s been gathering dust on the top shelf of a closet ever since. We used to play tons of DDR and Wii Sports so we like moving-around games but the thing just didn’t interest either of us, at all.

                Alyx just hasn’t been quite enough motivation for me to take on the project of figuring out how to get it hooked up and working, though I did at one point do the few minutes of googling to confirm it might work (I think it’s one of those Facebook ones, and as I recall it is supposed to work for Alyx but I’ll need some cable or other). Especially since it’s a fairly short side-story, it’s just not enough juice to be worth the squeeze.

                The conclusion of the series (until it’s not the conclusion any more—yeah, I know how franchises work, lol) though? That’d do it.

                If I already had it out and used it regularly I’m sure I’d have played Alyx by now, but with that being the only thing I have any interest in doing with it, just not enough to get me to set the thing up for that alone.

                • Philpax2 months ago
                  Alyx has implications for 3, and 3 will almost certainly follow on from Alyx, if that helps :-)
                  • phantasmish2 months ago
                    Maybe when I get that new Steam gaming computer (day 1 purchase… assuming the price isn’t crazy-high) I’ll get around to it.
              • BoGoToTo2 months ago
                It's kinda sad, with all the time an money spent on VR, HL:Alyx remains the only truly great VR game.
          • zbendefy2 months ago
            there is also a vr mod for HL1 as well
    • davepdotorg3 months ago
      There’s a great VR mod for Portal 2. Played it all the way through. Surprisingly comfortable to play too.
      • patrickdavey2 months ago
        I'm pretty sure I'd be vomiting everywhere! I'm amazed you found it comfortable!!
  • HelloUsername3 months ago
  • FrostKiwi2 months ago
    A Valve employee using YouTube Playthroughs [1] to diagnose a bug is hilarious to me. Awesome story.

    [1] https://mastodon.gamedev.place/@TomF/115589894339657055

    • lomase2 months ago
      Is Valve porting HL2 to VR? A 2013, sorry.
  • why_at2 months ago
    >a big innovation of HL2 was the extensive use of a real physics engine. The door and the guard are both physical objects, both have momentum, they impart an impulse on each other, and although the door hinge is frictionless, the guard's boots have some amount of friction with the floor.

    It's been a while since I've played HL2 but this isn't exactly how I remember it. While a lot of things were physics objects I thought the doors would just smoothly rotate towards their target position without any physics at all. You can't bump them shut with another physics object for instance.

    • sigmoid102 months ago
      You can't move them (apart from the opening and closing animation), but they can move other objects that are in their way. Both need to be physics objects for that to work, even though the door is just kinematic (i.e. it won't react to forces applied to it). Although if I remember correctly, they are not even fully kinematic. I think you could get them stuck halfway closed by cramming something in the door frame that would get the whole thing jammed.
      • Lammy2 months ago
        > I think you could get them stuck halfway closed by cramming something in the door frame that would get the whole thing jammed.

        This was a popular griefing tactic when TF2 first came out where you could trap everyone in spawn by crouch-jumping into the spawn door as Scout: https://youtu.be/JUPzN7tp7bQ?t=243

        • sigmoid102 months ago
          Yeah this seems to be exactly the same issue that Valve eventually discovered in the Mastodon thread linked by OP.
    • accrual2 months ago
      Just did some quick testing - the doors definitely have physics and can get stuck on objects and can impart forces. But unimpeded yes, they smoothly open/close.

      I stuck a tire in a door frame and tried to close it, the tire emitted a bunch of dust clouds as the two objects fought before the door finally ejected the tire at high speed.

  • accrual2 months ago
    > The door and the guard are both physical objects, both have momentum, they impart an impulse on each other

    I wonder if the term "impulse" here has any connection to the various impulse commands available in the source engine. I remember using "impulse 101" and causing havok in the opening plaza area. Spawning zombies on the roofs, sending them after the combine, etc.

    https://developer.valvesoftware.com/wiki/Impulse

    • WatchDog2 months ago
      The impulse console command originates from Quake, the Half-Life 1 engine (GoldSrc[0]), was based on the Quake engine, and the Half-Life 2 engine (Source), was based on GoldSrc.

      In quake, the impulse commands were used mostly to switch weapons[1]. I'm not really sure about the naming though, why choose the word "impulse".

      [0]: https://en.wikipedia.org/wiki/GoldSrc.

      [1]: https://github.com/id-Software/Quake/blob/0023db327bc1db0006...

    • ThrowawayR22 months ago
      • accrual2 months ago
        Right, I was just wondering if the developers repurposed the term impulse from the physics engine when creating console commands. "impulse 101" is a common cheat to give all weapons with ammo, but why not "give" or "player.addItem" or something? Just a curiosity.
        • sznio2 months ago
          As for the name "impulse", I don't know - but the way this command works reminds me of interrupts.

          The impulse command sends a command to the server instantly, rather than in the usual UserCmd sent to the server 30 times per second. They are used mostly for debugging, just assign #90 to your debugging function, then poke it from the console while the game is running. No need to change and potentially break the network code.

  • DarmokJalad17012 months ago
    I have encountered at least one bug at $job which was tracked down to x87 instructions. Our "production" build is deployed on embedded ARM CPUs while we have test builds compiled for x86 (32-bit) and x86_64 (different subsets of functionality). Anyway, the bug only showed up in the 32-bit x86 build. The same code worked fine in production and in the 64-bit test builds.

    It turned out to be an x87 bug where a piece of code was actually computing the wrong answer!. Logically following the code would make you think that the particular failure in question would never happen - and yet it did. That was quite a rabbit-hole to go into to figure out.

  • brokenmachine2 months ago
    Nothing to do with the actual story which was very interesting, but I just find it so absurd that in 2025 we're still splitting posts into paragraphs because of some weird historical character limit on tweets.

    And some of those posts are way longer than tweets used to be, but we're still splitting them for no real reason than to make them tweets instead of blog posts?

    • 01HNNWZ0MV43FF2 months ago
      Worse is better, it's easier to write inline on your Fediverse account than to write a blog post somewhere else and syndicate it
  • Panzerschrek3 months ago
    It seems to be typical - some calculations break while switching from x87 to SSE. The same happened with TF2 too - it's ammo calculation code worked slightly differently on GNU/Linux build of the game, because it was built with SSE instructions (Windows version still used x87).
    • arcfour3 months ago
      I think the only visible effect from that was the Engineer's metal, giving +40 or +41 from a small box, depending on the server platform (all classes technically do have metal, but the others can't use it).

      It was always fun to play on a new server and check what OS it was running that way, too. :-)

      • stoltzmann3 months ago
        And IIRC ammo for heavy and health for soldier!
    • MBCook2 months ago
      I’m surprised to hear the ammo calculation code would use floats.
      • bakugo2 months ago
        The game has ammo pickups that refill 20% and 50% of whatever your max ammo is, so floats have to be involved in there somewhere.
        • manwe1502 months ago
          Dividing by 5 or 2, respectively, are integers, if the game developers wanted them to be. More so because the actual units of ammo need to be integers if they are to render as full bullets each
          • shultays2 months ago
            Or more generalized "ammo += (maxAmmo * percentageToFill) / 100"
    • HaroldCindy2 months ago
      I expect this is / was a very common problem for people porting 32-bit game code to newer compilers. I work on a fairly old codebase that forces use of x87 for a handful of code paths that don't work correctly otherwise. GCC will use default to x87 if you do an i386 compile, but will default to SSE for 64-bit builds, so you have to be careful there too.
  • gambiting2 months ago
    I used to work at the studio responsible for the Driver games, and few years back we dug out the code for the original PC Driver and tried to compile it again, mostly for fun - we had to change a lot of hand written assembly code to make it build, and discovered that yeah, the game worked but none of the game replays worked - and it was for that exact same reason, better/different floating point precision issues. Really fun thing to investigate though.
  • Ericson23142 months ago
    It's a goal of mine to get Valve using Nix. (I hope our in-progress Windows support would make this especially compelling.)

    One advantage of this is that it will become very easy to not only build the original source of the game, but also build it with the original toolchain and dependencies, the toolchains for those dependencies, etc. etc., all the way down.

    Hopefully something like that at your finger trips would have made finding the root cause of this bug a good bit easier!

    • throwaway3141552 months ago
      > It's a goal of mine to get Valve using Nix

      They’re using Arch Linux. Let’s call it a win and move on lol.

      • Ericson23142 months ago
        Using completely different packaging infrastructure for the different platforms you support is no good!

        The goal with Nix should be that you can use the same infrastructure for all of Linux, macOS, and Windows. (And other Unixes, other OSes, etc. etc.)

    • zenethian2 months ago
      Nix seems like a cool tool but nix users are becoming increasingly irritating.
    • bpye2 months ago
      > I hope our in-progress Windows support would make this especially compelling.

      What is the current story for using Nix to build Windows binaries?

      • Ericson23142 months ago
        On Nixpkgs master, you can cross compile to MinGW and Cygwin.

        Native Cygwin builds are also currently in progress: https://github.com/NixOS/nixpkgs/pull/447520. I would expect this to be done very soon, there year even (holidays permitting).

        There is a MinGW build of Nix but it is missing some features. There has been MSVC build of a fork in the past and I would like to revive that also.

        There some some open questions relating to Nixpkgs's heavy use of Bash, but longer term I would like to compete for Windows in all ways:

        - Support all cross (MinGW, Cygwin/MSYS2, MSVC ABI with LLVM, MSVC with Wine) - Be Cygwin packages - Be https://github.com/msys2/MINGW-packages / https://github.com/msys2/MSYS2-packages - Be VCPKG

        All these things have slightly different trade-offs, and Nixpkgs is very good at portability, so we should simply do them all.

    • adastra222 months ago
      Maybe I'm not seeing it. How would the bug finding be easier here? Seems like the same setup. They could compile with recent tools, and they already had the compiled version with old tools (hosted on Steam).
      • Ericson23142 months ago
        You could quickly rule out non-determinism by reproducing the build with the new and old tools.

        You could also try the newer version of the codebase with the older tools (assuming nothing broke / no newer C++ features) if you like.

  • voidUpdate2 months ago
    Is there an alternative place to read this, for those of us with strict work network rules that consider mastodon as social media?
  • nasretdinov3 months ago
    I wonder how on earth stuff like x86->ARM translation works so well if games break even after switching from x87 registers to SSE preserving all the logic otherwise...
    • toast02 months ago
      I think x87 fpu is the only 'weird' floating point units left. I think if you stick with 64-bit double precision floats or 32-bit single precision floats, where the registers are also 64 or 32 bits, all the modern stuff behaves the same. x87 is just weird because registers are 80-bits ... the idea was to have more accurate results from more precision, but it ends up weird because if you run out of registers and have to spill to memory, you typically lose precision.

      Edit: since this post was second chanced, I can add on that some of the pre-PC consoles have weird floats too. If they had floats at all. Lots of fun for emulation developers. Even fun for contemporaneous game developers... PilotWings on the SNES comes with different revision accelerator chips and the demo only works properly on the early revision chips (but I think? the later revision chips have more accurate math). The PS2 FPU has weirdness around NaN, Infinity, very large numbers, and denormalized numbers. Etc.

      • kineticdaffodil2 months ago
        What about arm, with software floats its compiler depending?
    • ErroneousBosh2 months ago
      It's probably because you have to have weird precision issues where the numbers are calculated ever so slightly differently, and some other effect like a guard being slightly too close and getting clipped by a door where that difference matters.

      I debugged some software synthesizer code a while back (like 20 years or so now I think of it) where a build of it on one platform failed because of a precision bug. I can't remember the details, but there was a lot of "works fine on my machine" type discussion around it. Anyway it relied on a crude simulation of an RC circuit reaching very close to 0 asymptotically to trigger a state change, but on something like 64-bit Intel with a specific processor it never quite made it low enough to trip the comparison because of something to do with not flushing denormals.

      From an electronic standpoint, making it simulate "it's high enough" as being about 0.7 and " it's low enough" being about 0.01 was far closer to the instrument they were trying to simulate, and making it massively imprecise like that got it going on everything.

      • lomase2 months ago
        Is funny because the only code I have read that flushed denormals was in synth code.
        • ErroneousBosh2 months ago
          Denormals in audio code are kind of the "perfect storm", because they take ages to deal with - you're suddenly back into softfloat land - and because you have to deal with many thousands of them in a few hundred microseconds.

          We take how fast hardware floating point is for granted. I suspect it would be interesting to compare something compiled with softfloat with a normal benchmark and see just how bad it is.

          It's a great reason to do your DSP code in fixed-point, which is just integer with a couple of steps you have to write down on paper to keep straight until you get to the end. Or, I do, because I suck at arithmetic. Just do it all in machine-length signed ints, and forget all the mystical world of tiny tiny floating point values ;-)

          • lomase2 months ago
            Fixed floating point has been a mistery to me, and to be fair floting point is too. I know digital synths like Virus or Waldorf all used 24 bit fixed point math DSP.

            I remember this dps site with lost of c and delphi code, there is where I found what denormals are.

            Nowdays I dont see DPS code dealing with denormals. Maybe the CPU does not have to do it in software anymore? I don't really know.

            • ErroneousBosh2 months ago
              > I remember this dps site with lost of c and delphi code, there is where I found what denormals are.

              musicdsp.org?

              > Fixed floating point has been a mistery to me, and to be fair floting point is too. I know digital synths like Virus or Waldorf all used 24 bit fixed point math DSP.

              If you imagine scaling a 16-bit value for like a volume control from 0 to 1, then you'd have maybe 32767 for maximum positive, and -32768 for maximum negative. You could convert those to floats, multiply, and convert back to a 16-bit integer.

              But you don't want to use floats, you want to keep it all integer. So you make the volume range be from 0 to 255, and multiply your 16-bit value by that. Now you've got a 24-bit value, with a "binary point" between bits 7 and 8. Now the output is way off scale for the 16-bit DAC but if we chop off the fractional part by just shifting the result of the multiply left 8 bits, you've now got your volume control.

              Some DSPs will actually do a 16 bit by 16 bit multiply which just discards the lower 16 bits of the result, with the assumption being that both 16-bit values mean "-1 to 1".

    • torginus2 months ago
      I remember there was a huge scandal where Intel's compiler, icc (considered to be the fastest for quite a while back when) defaulted to x87 when it detected an AMD CPU instead of SSE, giving AMD cpu's a handicap (incidentally, that's the reason why x87 used to be much faster on AMD for a while).

      A lot of games were shipped with icc, so my guess is they'd work just fine as they were tested with both.

    • pdw2 months ago
      Rosetta uses software emulation for x87 floating point. That's slow, but in practice that doesn't matter much. Mac software never had a reason to use x87 FP, every Intel Mac had at least SSE3 support.
      • ksherlock2 months ago
        There was at least one reason...

            long double x87me(long double a, long double b) {
                return a+b;
            }
        
            pushq %rbp
            movq %rsp, %rbp
            fldt 32(%rbp)
            fldt 16(%rbp)
            faddp %st(1)
            popq %rbp
            retq
        • adastra222 months ago
          what is this?
          • Tankenstein2 months ago
            Looks like a demonstration that using `long double` math requires dipping into x87 instructions, specifically the `fldt` instruction: "floating point load ten bytes".
  • dev0p2 months ago
    >But on the SSE version, a whole bunch of tiny precisions are very slightly different, and a combination of the friction on the floor and the mass of the objects means the guard still rotates from the collision, but now he rotates very slightly less far.

    Insanity. The values were just right. Just wow.

  • YouAreWRONGtoo2 months ago
    [dead]
  • netsharc3 months ago
    Meta: I'm going to make a Twitter clone that bans you if you use it as a multi-paragraph blogging platform... god damn !#@#%!!!.
    • bathtub3653 months ago
      Here’s a link with the thread unrolled onto a single page: https://mastoreader.io/?url=https%3A%2F%2Fmastodon.gamedev.p...
    • tiborsaas2 months ago
      I feel you, it's super annoying.
    • viraptor3 months ago
      Do you actively want the linked thread to not exist? Because not having this posting option does not mean it would appear anywhere else.
    • fragmede3 months ago
      I'll make one that's the opposite (your post must be at least two paragraphs and an LLM is going to judge your text to make sure it's not lorum Ipsum) if you'll help me get users.