At 35, I have the same goal and feel that I've actually made quite a bit of progress and am working on some very interesting projects. I'll share some of my secrets with you:

1. When you find an issue in code, search the entire codebase for it because it's probable that the mistake has been made before. For example, I once used strncpy instead of strncpy_s which got flagged in the code review. After I learned why I searched the codebase and I had done that several times before that hadn't been caught in code reviews. I could have made my week easier by not doing this, as fixing the codebase resulted in additional time, more code reviews, and more embarrassment that I made a stupid mistake many times before my team noticed. However, if I hadn't, then we could have had customers experience issues in the future, which would have been far worse.

2. With any project, build out an extensive structure of resources personally curated by yourself. Get used to documenting everything you learn, even if it is just notes to yourself, but the more the better. At my job, in my file storage area, I have a folder for documentation, a folder for tests to run, a folder for things to install to set the tests up, a folder for customer cases, a folder for freeware that I use, etc. I'm constantly building these out the best I can. Make sure that it's an area you have complete control over so that you can control the organization of it.

3. Keep track of the issues that make it out to the public, even once they are fixed it takes customers years to update so you will be hearing a lot about any issue that gets out. My team recently changed a lot, so after the dust settled I asked for a few months to do some research. I used a lot of that time to build two spreadsheets. The first is a list of every customer case that was resolved, whether the issue was on their end (environmental) or on ours, and what the issue was. The second spreadsheet was a list of issues on our end, what versions they were introduced in, what versions and changesets they were fixed in, what to look for in the logs to detect the issue, and so on. I put these files in my folder for customer cases. Then, I used the info I gathered to create a script to scan logs, look for lines of interest, and output that a probable issue has been detected.

4. Realize that other people aren't going to do these things, even if they are good developers. I've become one of the core programmers and have survived multiple layoffs. My section of resources, my logging scanner, my issue spreadsheets, they are all out in areas publicly accessible to the other devs and it doesn't matter. I'm not afraid of becoming redundant and being replaced because my knowledge is out there. Rather, it's the exact opposite. The rest of my team, even though they are skilled programmers, are not going to do the same things that I do even if I explain all the details to them on how to keep track of everything. Instead, they are constantly amazed that I can often solve issues that pop up immediately.

5. If someone finds a tool too complicated or confusing, then the issue is not with the person, but with the tool. Often as developers we are responsible for how tools are presented and explained but not who the user is. As such, it is tempting to say that the problem isn't with the tool we built, but with the "stupid" user. I call this view "Linux mentality" because I find many (of course not all) Linux users have a "git good" type attitude where they think the solution is for people to spend a vast amount of time and effort learning to use clunky tools, instead of finding better tools.

My favorite example of this came from this very forum: a comment on a post once actually said that if you don't know how to use the command line, then you have an "extreme addiction to IDEs", are "dumber by the day", and "you will be replaced by lesser skilled cheap labor inevitably". He never once thought that maybe the command line should be replaced with something better. The other example I have of this is in school when I was telling a classmate about software that I had written. He asked me why I had written it as anyone could write a script to do what I was doing. I told him that while he could write a script, my mom sure couldn't. In other words, I view complicated tools as an opportunity to either fix the tool or to write my own competing tool instead of expecting users to spend their precious time and effort overcoming the complications.

6. So far this has all been about working with people, which is the often overlooked part of programming. However, I have a secret about code as well: programming is a broken mess because it is over-complicated. Just like my last point was that complicated tools need to be fixed to be simpler, all of programming is complicated and should be simpler. At the end of the day, programming is just about defining functions and datatypes. Classes, constructors, destructors, exceptions, many of these things started out as ways to make programming easier but try to teach programming to a newbie and you'll see just how much of what we think is fundamental to programming is hard to explain why we do them.

In particular, the crux of my hot take is that I think Object Oriented Programming (OOP) is a mistake and a dead end. I'm not saying that you shouldn't use it. I'm saying that I think the jump from Procedural programming to more organized code made a mistake by going to OOP. Many people don't even realize what a class actually is: a grouping of a user defined datatype and a set of functions that invisibly take a variable of that datatype as its first parameter (Python in particular makes this more apparent by turning the invisible first parameter into a visible parameter named self). I have my own ideas about what programming should be instead of OOP, but its going to be a few more years before I'm ready to talk about it publicly, so I'll just leave this as a little teaser: both OOP and functional programming over complicate the ideas of programming and turn the entire field into a giant mess that takes years and decades to learn. I think they have missed the mark, and that there are other ways to fix the problems that procedural programming has. Until then though, it's probably still best to use OOP, but in the meantime, make sure you understand what a class actually is.