Hacking Terraria: Did You Know?

Discussion in 'PC' started by Rydian, Nov 5, 2012.

  1. Rydian

    Rydian Blood Crawler

    Note: All my hacking has been OFFLINE, on my single-player worlds.

    So I've been using Terraria for hacking practice for a while now, and while messing with it I've discovered all sorts of fun little tidbits of info that I figure people here might like to know... so here's a "did you know?" thread!

    Important clarification...
    Show Spoiler
    Terraria runs according to the screen's vsync, NOT a proper timer. This means that if the game starts visually lagging it'll start logically lagging as well. For example if invincibility is supposed to be 2/3rds of a second, it'll be longer when you're lagging. This is important to keep in mind when reading the following information, since I mention frames/timings for some things.

    This also means that it's easy for a lagging player to get out of sync with the host. This is a common cause of monsters "teleporting" in multi-player wheh they don't in single-player. What's happening is when your game lags, the monsters move slower (and their AI reacts differently because of the different positioning) on your game, so you'll see monsters in a different place than they're supposed to be. When they "teleport", that's the monsters catching up to what's supposed to happen, they're teleporting to where they SHOULD be (since your game lagged and moved them out of sync/place).

    1. It's possible to have over 400 max HP. The hearts don't make another row, they just continue off the screen... The max value doesn't seem to have a technical cap, as it's possible to have over a million max HP.

    2. Health restore rate depends on your max health. This can be seen somewhat when comparing 100 max health to 400 max health, but it's mostly noticeable when your max HP is really high (where the game can restore 50HP a second to you).

    3. MP, on the other hand, seems to have a hardcoded limit of 400 max. Anything higher only counts as 400... even values obtained legitly-in game (according to the wiki, you could reach 480 max MP if it wasn't capped at 400).

    4. Maximum air is variable! The base value is 200. When in water, you lose one point of breath every 7 frames (without modifiers like the diving helmet, meaning it takes ~25 seconds to lose all 200 points of air). When out of water it regains at a rate of 3 points per frame. Unfortunately there's no items still existing that edit your max air, and the player data does not save or restore this value, so if there were any items or plans to make change your max air, they were scrapped a while ago.

    5. Hate lava? Apparantly the devs do as well! Obsidian Skin is the first buff/debuff ID, which points to it being the first one either designed, or completed. On the other hand, buffs like Fairy are at the end of the list, since they came last.

    6. Non-stackable items in inventory apparantly have IDs. If you directly clone non-stackable items (tools, armor, etc.) in-game and then shift-click one of them, ALL of them will join together into one entry in your trash can, condensing them all back into one. However if you save and then load the game, the cloned items become stable (gaining their own IDs).

    7. Fire and poison damage use the same damage function, so logically one started as a copy-paste of the other (and they do the same amount of damage per second).

    8. The default invincibility time is 40 frames. Assuming a refresh rate of 60 fps (which is what Terraria erroneously needs to run properly), this is 2/3rds of a second.

    9. Rocket boots start with an internal meter value of 7 (not frames!). This is an integer so it can only be reduced by whole numbers at a time. This is why you can only fire off a lone pair of rocket boots up to 7 times before needing to rest. You can fire off the seven spurts individually, or chained into one boost, it doesn't seem that one way is more efficient than the other.

    10. Wings, on the other hand, start with an internal value of 90 frames (one and a half seconds when not lagging), and can be reduced by as little as 1. While it's still an integer, this gives much more freedom in how you want to spend the "charges" during a run/jump. This means that wings are a lot more maneuverable than rocket boots.

    11. Wings don't start subtracting from their charges until the peak of your jump. Even though the animation starts immediately, that's just for show.

    12. One block is about 16x16 game units. Your positioning (x and Y coordinates) are kept as floats, and they're stored to a precision of five decimal places. So the game really keeps careful track of your positioning! Even if you move so little left or right that your sprite doesn't move, the game still keeps track of your movement. Too bad the physics in the game don't take this precision into account...
      <edit> The first number in the coordinates picture should be 33884, not 33384... </edit>
      <edit2> Fixed the numbers, as posted later in the thread.</edit2>

    13. Double jumps are coded in such a way that only one is possible before landing. If the team intended to add items to let you jump more than once before landing, they'd have to edit the existing code to do it.

    That's all I've discovered for now.

  2. This is some interesting stuff. It's quite intriguing how they made every player sync to his frames, I did not realize that. Thank you for this informative piece of trivia.
  3. celo753

    celo753 Clinger

    About the cloud in a bottle thingy, That means mods allowing for triple jumps are impossible?
  4. Rydian

    Rydian Blood Crawler

    Thanks for the response. ^^ The vsync issue has been known for a while (it really messes with people who have 50hz or 75hz displays), I just felt it needed to be known for some of the frame/timing numbers.

    No, but they'd need to modify the code Terraria uses for double jumps right now (the game code used when jumping, not just editing an item to set double jumps to 2 or more).

    Currently what happens is that when you're touching the ground, one of these two codes is called every frame.
    If you have boots...
    mov byte ptr [eax+0000024C],01
    If you don't have boots...
    mov byte ptr [eax+0000024C],00

    The eax+0000024C is a pointer+offset to the address in RAM that holds how many double jumps you have, and the 00 or 01 is the value that's set. So every frame that you're touching the ground, the game continuously assigns you either 1 or 0 double jumps left (depending on if you have the boots set or not). The first guess is that setting this value to 2 or more should allow for two or more double jumps... but it doesn't, because this value is not subtracted.

    Here's the code that's called when you perform a double jump.
    mov byte ptr [eax+0000024C],00
    This code does NOT subtract 1 from the double jump value like you think it would, it explicitly sets the number of remaining double jumps to 0. This means that no matter how many double jumps you set for yourself, they're set back to 0 whenever you do a single double-jump.

    Modifying this code to actually subtract the value...
    sub byte ptr [eax+0000024C],01
    Does allow multiple double-jumps in a row.

    Now, the exact codes given here are the game's "output" assembly, the game is written in .NET so the way the game is actually modded (I assume using reflection) would be modifying differently-looking code, but the concept is the same. The game currently explicitly sets double jumps to 0, when it needs to subtract by one.
    Dragonized likes this.
  5. nababoo

    nababoo Dark Caster

    This is really interesting, and has potential uses with the modding community. It also sheds some light on the coding process :p

    Hope you continue with further exploits.
  6. Rydian

    Rydian Blood Crawler


    I could say a lot of things about the underlying code, but a lot of it doesn't actually deal with how people play the game (or rather, situations they would ever encounter) and are more for trivia, so I didn't post them... but sure, if people would like updates I can toss out more info.

    • Max HP is interpreted as a signed value, so it can actually be negative (along with current HP). With negative HP you die in one hit, so it's not exactly useful... unless somebody wants to mod in a challenge, making it so players always die in one hit (unless they wait for their health to regenerate back up above 0). Also when Max HP is negative, the further back from 0 it is the more to the left it's positioned on the screen for some reason.

    • Max MP is signed as well, but when negative it won't display so 0 to 400 is all I can accurately test. That said, if max MP is a value that's not a multiple of 20 (such as the 137 in the screenshot), it won't display part of a star, it rounds the "star number" down. This means that if you have between 0 and 20 max MP (non-inclusive), you won't have any visible stars (though the word "Mana" is still there).

    • When you equip both rocket boots and wings, the rocket boots themselves are ignored and the game instead increases your wings duration to 160 frames. This isn't double the normal range (it'd be 180 frames then, so you're 1/3rd of a second short of double flight time), so it stands to reason that rocket boots last a bit less time than wings (though I don't have any easy measurements to test).

    • The time of day is stored as a double for some reason... double is a double-precision floating-point, which is generally used for numbers that need a good number of precise decimal places. The thing is, it only goes up to less than 64,000, and none of my pokes at it have shown it ever having decimal places, it's treated as an integer... so it could easily be stored and manipulated in a 4-byte value instead (hell, it'd fit in two bytes, but Terraria is not exactly known for efficiency). This number is actually a count of frames... and it counts the current cycle, not the total time. So starting in the morning at 0, it counts up to 54,000 (the number of frames in 15 minutes at 60FPS) and resets to 0 when it hits night, then counts up to 32400 (the number of frames in 9 minutes at 60FPS) and resets to 0 when it hits day (to start over).

      This value can be frozen or modified to affect that time of day as needed, and making it negative bugs out the lighting, as the game can't figure out what the hell something like "negative 2:30 AM" is supposed to look like.
      According to the game, negative AM time is supposed to look like hell. XD

    • If you get inside some solid blocks, you'll be fine... unless it's sand or silt, which are programmed to hurt you while you're inside them (to simulate suffocation). However if you work your way inside other blocks (easily hacked as the game uses float x/y coordinates in two variables right next to each other, with Y increasing going down) you'll find they don't cause you any damage, since Redigit and such didn't think players would normally get inside solid blocks that don't fall (so they didn't program all the other blocks to hurt you).

    • Items in the inventory are four bytes large. This currently means a good number of items can fit in the game (assuming two bytes for the item ID giving 65,535 possible different items (only one byte gives 255, not enough for a game like this), one byte for something like the reforge ID, and the last byte used for technical information such as a bitfield)... but the inventory system would need a lot of various mods in order to do stuff like naming specific items or adding additional properties.

    • Fall damage and monster/projectile contact damage are treated almost the same by the game (and infact use the same routine for subtracting health), except for the below.

    • Temporary hit invincibility does NOT protect you from fall damage.

    • Your air meter only shows when the air is less than the max (default 200 as I mentioned earlier). This means that if there's some sort of hack or mod in place to make air never go down, then the air meter won't even display when you're in water.

    • There's actually two internal damage routines for monsters. One is used for normal monsters, and the other is used for worm-like enemies. This can be seen in one of my early hack attempts, where normal monsters die in one hit, but worm enemies don't.

    • Buff timers can be edited as you please, but minutes are the biggest unit they count.

    • Buffs and debuffs are in the same list together and use the same countdowns, so other than the ability to right-click buffs to remove them, they're the same sort of thing. This means that disabling the buff countdown timer will make debuffs ("On Fire!", etc.) infinite as well (the nurse still removes most of course).

    And if you want to see some other weird crap, here's a video I recorded showing some failures and interesting effects I got when trying to make invincibility...

    And here's a screenshot of when I really screwed up a hack...
    Check out the torso at the top of the screen. XD

    And here's some earlier videos of basic fiddling around I did.

    This (and the first post) is pretty much all I've got.
    Dragonized, Cricket, Oranje and 5 others like this.
  7. zebri

    zebri Icy Merman

    You officially broke the game.
    The negative 2:30 AM reminds me of blood moon, tho.
  8. You, Sir, are a gentleman and a scholar.
  9. nababoo

    nababoo Dark Caster

    This is amazing stuff :O
  10. celo753

    celo753 Clinger

    Can you try negative 5:00 AM? That'd be hellish.
  11. Rydian

    Rydian Blood Crawler

    Doesn't look much different.

    Also would anybody be interested in seeing a video of the hacks I've done that work? It wouldn't be as interesting as this stuff, it'd crap like permanent invincibility after you get hit, eat one heart crystal for 400 HP, infinite rocket boots/wings, free crafting, infinite potion use... you know, full-on cheats.

    Other than that I doubt there's much else I'll do, I've already hacked most of the crap I want with the game and haven't had any other spectacular failures or interesting findings.
  12. celo753

    celo753 Clinger

    Can you try changing the time to something like 30:00 PM? I wonder how it would look like if you put it above the limit.
    nababoo likes this.
  13. Rydian

    Rydian Blood Crawler

    If it's above the limit the game immediately changes it to the beginning of the next cycle (day or night).

    The video would have voice commentary, me explaining some of the coding behind some of the features of the game and such.
  14. Voyager

    Voyager Face Monster

    I was waiting for someone to hack this game. I've seen that blocks don't hurt many times while making obsideon and ending up inside it.
    I've always wanted infinite rocket boots.
  15. Rydian

    Rydian Blood Crawler

    I don't know if I'm going to release the hacks publicly, since a good chunk of them worked online last I checked and I don't want to contribute to griefing... I do know that Tshock includes anti-hack stuff, but back when I played publicly it was so inaccurate that I got banned from a few servers just playing normally... so I'll have to see if it's improved (and actually catches all the worst stuff) before releasing this.

    However I will make an example and commentary video, about how I hacked each type of thing and my thoughts on the code and random findings.
  16. nababoo

    nababoo Dark Caster

    A SP version would probably be for the best -- we don't want to further increase the anarchy of servers. *shivers*

    Either that, or you can make the installation so complicated only the smart people can use it :)
  17. Empio

    Empio Blazing Wheel

    Floats by default are only precise to 5 decimal places.

    A block in Terraria is 16x16 - the 36 comes from your player's collision box being 20 pixels wide.

    The reason for HP and MP being signed values is to make them easier to clamp between 0 and their max value.
    If an unsigned value goes below zero, it wraps around and can become a number close to the maximum value for that data type.

    Items are 4 bytes because that is the size of a int pointer (points to the address of the Item in memory).
  18. Rydian

    Rydian Blood Crawler

    Unlike other things which hook into the game via reflection and can thus access a lot of the data in a high-level fashion, this is straight-up assembly modification... so something like detecting if the game is going into online mode (and then disabling itself) is more complicated, and seeing as it's likely just a variable change (if I'm lucky and can detect it) it could be edited in the same way (by another outside program), it wouldn't be much work for somebody to disable that type of protection in this type of trainer (say, a small standalone program that hooks and changes it), and I'd need to toss in some sort of debugger detection, but then they could just have the other program hook, make a change, then unhook and destroy itself, and even getting to that step is more work than I care about.

    And then there's the issue that people wouldn't be able to use this for multi-user builds... whereas if they're doing this in a small group they could just run the vanilla software to get past tshock's cheat protection, if the trainer needs to disable itself in multiplayer mode then there goes that ability (and a lot of the reason to distribute it, inventory editors are fine, but infinite rocket boots makes building large structures much quicker).

    Well it's a standalone tool (I personally detest when installs are required for tools that run standalone), but I suppose I could distribute it in some wacky fashion like split up into hex chunks a user needs to piece together in a hex editor... XD That'd be silly though, as it'd only take one person to put up a "fixed" version for it to spread.

    Being required to add in various forms of protection is just going against my laziness... I'm using Terraria for experimentation and learning, if I need to add in a bunch of specific protection to stop this from working online I don't even feel like releasing it since it'd be a choice between "do a bunch of work to let other people use it" or "do nothing else and go watch Pawn Stars or something".

    I downloaded Tshock 3.7.x and the 4 prerelease (in case detection of cheating is different between them) and will run some tests later. If only 4 is decent at kicking me off when I've got some of the potentially-destructive hacks active then I'll wait until it's stable and people are told to upgrade. If neither are, then I'm not going to push this here because even though a ton of it was done to make building large structures easier, it can also easily be used for griefing (infinite dynamite to blow up a mountain you want to flatten could also blow up other people's worlds).

    If they used a double for it I'd be even more surprised, as it is you can already scoot less than a visible pixel in one direction multiple times just with normal keyboard input (quick human-possible taps) without affecting most calculations.

    Pfffft, wow, geometry fail on my part, thanks, I'll correct it later. That explains why my value wasn't a power of 2... I was (obviously) working with the numbers to jump my character over a certain number of blocks at a time, to move through walls without destroying them, to make getting around large creations easier.

    The value dipping below the base is currently accounted for as it is and would work just fine , though I suppose Terraria is written in a high-level language where something like ($curr_hp < 0) is more commonly written than something to test if the leftmost bit (or whichever marks it as negative) is a certain value...

    The game seems to use four bytes (or float/double) for most things when it doesn't need to (at least when it comes to player stats), which is why the inventory being limited like that stood out, and people asked about modding so I figured it should be pointed out (as people have talked about adding new aspects to items and junk) that it'd need to be expanded.
    <edit> Okay, I see what you mean now, yeah it's literally pointers to the actual location of the item data. This explains the behavior of items when I "cloned" them just by copying the pointer data round... I ended up making multiple slots in the inventory that referenced the same item in memory. </edit>

    You know, in addition to the fact that it re-assigns lots of memory locations the exact same value every frame, over and over. I'm really starting to see why Terraria's so slow for what it is... and it's not just from being written in a modern rapid-development language. It's just written lazily in so many places. Way too many checks and sets are happening in the main logic loop...
    Oranje and nababoo like this.
  19. Berserker66

    Berserker66 Umbrella Slime

    First of all, this is not hacking, just datamining/reverse engineering.

    Secondly.. it hurts.

    All the frame related problems or technicalities.. well Redigit worked with a framework intended for consoles which usually have set framerates. Using it for PC without properly adjusting .. is just a beginner's mistake.

    No it's a 32 bit signed integer, you can have (2^32-1)/2 hp. Which, yes, exceeds a million, but there is a technical cap.

    It's exactly 16x16 "units" which Terraria translates directly to 16x16 pixels because it uses a 1:1 orthogonal projection.The position is kept as double (or was it float?, can't be arsed to check). The 5 digits precision is simply how much your print statement gives you by default and has nothing to do with the actual precision ingame.

    This was the case from version to version. Redigit really loves hardcoding his stuff and had to make major code rewrites on low level stuff to get new features working. Terraria was his first large project and he had no experience to software growth.
    Dragonized, nababoo and Jeckel like this.
  20. Gmodlol61

    Gmodlol61 Necromancer

    Amg this is some hilariously cool stuff
    Are you going to try hacking starbound?

Share This Page