I notice that for me there are two distinct steps to writing useful software. The first step is to just get it working. If it doesn’t work, then it’s not going to be useful to anybody.
But then after that, there is the question of making it useful to people who are not me. Not only should it be useful for the particular problem that I am trying to solve, but it should also be able to help other people to solve different problems.
To make things useful for other people, I need to pull out all of the independently useful bits, give each one an interface that is clean and easy to use, and all the while make sure that I haven’t broken anything. When all that is done, then I can go on to working on other projects.
So every time I solve a problem for myself, I am also creating new tools that can help other people to get things done. Most other programmers also think and work this way.
Which means that for most programmers, the act of coding is inherently generous. The ability to continually build useful tools for the community is one of the wonderful things about programming.