Hacker Newsnew | past | comments | ask | show | jobs | submit | PlunderBunny's commentslogin

Didn’t Apple do something with triangulation of known WiFi hotspots in the days before the iPhone had GPS?

“If your Naomi is Klein, then it’s green…”

It’s (slightly) easier to type www than web.

I figured out that, in the early versions of Realmz for the Mac, there was an enchanted item (a helm?) that added a few points to the wearer’s stats when equipped, but when removed it took away more than it added (i.e. left you worse off). It only took a few seconds for my programmer brain to start me furiously equipping and then un-equipping it, and sure enough, when that stat went to -127, one more equip-and-unequip was sufficient to give me a +128 bonus for that stat.

I never understood how that particular bit of logic could have been coded that way - it seemed so unnatural.


There were games being written in days where every byte was precious, and the indirection necessary for something like the decorator pattern was just infeasible. There was a lot of direct stat manipulation upon equip & unequip back in the day.

Following that there was the era in which the only way to be competitive in the games space was to write in assembler directly, which would be my guess for how the bug you described happened, since a more sophisticated algorithm should probably have fit just fine by the time we're in the color Mac era but it would have been more painful to write, and nobody has any time for that. Lots of bizarre shortcuts were taken in this era. Some of the posts from Raymond Chen about Windows providing backwards compatibility for games of this era give an idea of the situation, which are related to how the games interacted with the OS rather than with game mechanics but it's a similar process.

Finally, games have this perverse effect going on where if you write down a bunch of effects you want things in your game to have ("armor can add % bonuses to this part of the strike calculation", etc.), it creates a set of boundaries within which the game's systems can function, and the ironic effect of the creation of those boundaries is to immediately bring to mind ways of violating those boundaries and demands from the designers to do so. These violations of the boundaries will tend to be buggy.


I would figure the reason was because calculating it based on your inventory every time it's needed would've been expensive, so the developers decided to cache it, but instead of recalculating it from scratch when there's a stat change, they decided to try updating it incrementally, but I guess also imperatively. A string of mistakes has to happen to lead to such a situation but it doesn't seem super unnatural to me.

I wonder if it was percentage based. That'd be one of the easiest mistakes to make.

- Player has a stat of 100

- Wears "+10%" helm

- Player has a stat of 110

- Removes helm, game subtracts 10%

- Player has a stat of 99

Actually, now that I think about it more, that wouldn't work as described above because once your stat got close to zero you'd enter a kind of Zeno's Paradox situation.


it's more likely that the stat for equipping is calculated differently to when unequipping (ala, "same" code in two different places, and one got modified at some point and forgot about the other).

> I wonder if it was percentage based. That'd be one of the easiest mistakes to make.

How would that be one of the easiest mistakes to make? There are no operations for working with percentages, nor is it a thing you'd want to do.

To make that helm work as you describe, you'd need to multiply the stat by 1.1 when equipping the helm and then by 0.9 when deequipping it. But at that point you've lost any justification for making the mistake; those are just two random numbers that don't cancel each other out. It's not like you're adding a number in one place and then erroneously subtracting that same number somewhere else.

(Also, these are very strange multipliers to use this way, because they can never produce exact results. You're bound to see rounding errors if you insist on update-when-equipping and update-when-deequipping instead of recalculate-stats-when-equipment-changes.)


That exact sort of magic numbering is rife in games from what I've seen over the years, especially in stuff like an old RPG from 1994. Maybe you've seen better game code on average than me. But you don't even really need the "random numbers" - I'd expect a mistake like:

    GetItemChange(curVal, percentBoost) { return curVal * PERCENT_BOOST; }
    
    eqipVal = val + GetItemChange(val, percentBoost);
    // ... later...
    unequipVal = val - GetItemChange(val, percentBoost);

Edit: I see there's Realmz source code on GitHub.[1] Although I can't see anything that'd cause the specific bug PlunderBunny mentions (they did say 'early versions' so maybe it was fixed), this is the kind of thing I mean re old games and "random numbers". This is part of the Wear method for equipping items:

    if ((item.sp1 > 59) && (item.sp1 < 100))
      c[character].condition[item.sp2] = 0; /**** neutralize condition ***/
    if (item.sp1 == 122) /******** item adds attacks **********/
    {
      c[character].attackbonus += item.sp2;
    }

    if ((item.sp1 > 19) && (item.sp1 < 60)) /******* adds condition *****/
    {
      if (c[character].condition[item.sp1 - 20] > -1)
        c[character].condition[item.sp1 - 20] = 0;
      c[character].condition[item.sp1 - 20] += item.sp2; /**** make condition[sp1-20] = sp2 ***/
    }

    if (item.sp3) /******* adds special ability *****/
    {
      if (item.sp3 < 0)
        c[character].special[abs(item.sp3) - 1] += item.sp5;
      else if ((item.sp3 < 16) && (item.sp3 > 0))
        c[character].spec[item.sp3 - 1] += item.sp5;
      else
        partycondition[item.sp3 - 30] -= abs(item.sp5);
    }

    if (item.sp4) {
      if (item.sp4 < 0)
        c[character].special[abs(item.sp4) - 1] += item.sp5;
      else if ((item.sp4 < 16) && (item.sp4 > 0))
        c[character].spec[item.sp4 - 1] += item.sp5;
      else
        partycondition[item.sp4 - 30] -= abs(item.sp5);
    }
  }
[1] https://github.com/Realmz-Castle/realmz

Never mutate the source of truth

(caveats of course): memory and processing is restricted on the old systems; so these kind of simplifications might be the only way to deliver a big game

If you still like video games and are a bit of a masochist you might try playing Noita sometime, a lot of the late game is basically built around this type of logic.

For example there's a wizard-type enemy that temporarily debuffs your max health by 50%, and the effect can stack if you get hit more than once. But what happens if you pick up a permanent health boost item while the debuff spell is on you? You gain the normal health boost, then it multiplies itself when the wizard's spell expires; you can can go from 100 to several thousand HP in seconds and there's basically no limit.

In any other game this would be considered a bug and patched out in the next update. NOT NOITA, motherfucker. You're almost required to do things like this for a lot of the end-game optional content.


The programmer adjusted the way it works to make it slightly less OP. Just so we could all be sure the bug was now a feature.

Ah I haven't played in a long time, though it's good to see there's still some active updates


Noita is mad, in the best sort of way.

So it is this very hard amalgamation of rogue and powder toy that controls like terreria, Very hard, With none of that silly meta progression nonsense you find in most roguelikes, But you push through, get good and beat it. Guess what? That was at most 10% of the game(probably closer to 1%), the other 90% is deliberately obtuse, hidden and optional. What sort of madmen make 90% of their game a easter egg?


I haven't thought about Realmz in a long-ass time. It had some really crazy tracks and was the only game I know of that used MOD instead of MIDI for its music.

Deus Ex Used MOD, At least I think they were mod, There were a fair number of what was basically MIDI + samples formats.

Also while trying to get my facts straight (All I remember was trying to find a mod player to play the deus ex music found on the cd) apparently Unreal tournament and tyrian2000 used mod music as well, Someone at Epic Megagames must have liked them.


Oh man you're right. How could I forget about Unreal Tournament? I totally forget that mod player I found, but it was fun to cobble together playlists.

By the way if you liked the Deus Ex soundtrack you can check out the Sonic Augmentation ocremix album. Really good.


round(stat * 1.05); // rounded down round(stat / 1.05); // rounded down again

that would be my first guess.


Sounds like a third-party keyboard opportunity: “Just like the standard Apple keyboard but not ML”.

I’m sure I’m not the only programmer that developed a habit of resting my finger on the F5 key at a certain point in my workflow, and then had to unlearn it just because of the stupid touch-bar (Still using my 2019 Intel MBP with stupid touch-bar).


Haha - the number of times I’ve accidentally hit F1 and ended up looking at some variation of ‘page not found’ in Edge…


I think it's usually my IDE. I haven't seen it recently; not sure if I disabled it in a fit of pique, or if it just doesn't do that any more? (/me goes and tentatively pokes F1 on purpose for the first time in decades... yeah, it's the latter).


The only winning move is not to play.


I wonder why it has 'photomaxmix' just sitting at the end of the 11th paragraph?


In a shared source, I wonder if it would be useful to make a theme that used brighter colours for segments of code that were more ‘contentious’, I.e. had a lot of changes? I guess it doesn’t work because a lot of contentious code is re-written (deleted and re-created).

Or maybe newer code could be brighter, and older code (not touched for a long time) could fade?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: