First, all my development falls into two piles:
Process Control
Data Gathering
and I go in with an idea of the visualization to be used, and a visual (hopefully accurate dwg files) of the machines, and electrical drawings.
Then I go top down, take on the perspective of the product (literally personify in my twisted mind) and write the program based on the transformations encountered by the product. I then have a flow chart, steps list, and parameters for the machinery, and I want up front to know about any upstream and downstream equipment and existing or desired interfaces.
That main flow becomes the spine, the overview, the top of the project, and each of its logical sections are quartered off and chopped into ladder logic with no regard for address, only interface bits of the correct binary sizes and shapes. We'll deal with the electrical and I/O addressing later. If I have a section that I don't know how to solve, feels too big, I skip it and move on to the next one, or break it into smaller pieces. Then I go after low hanging fruit and solve all the pieces I know how to solve, leaving me time to stew on the hard ones, and come up with ideas, and sometimes test them in advance until I am sure I have working code even if it might need adjustment at start up. If it does, it gets linked over to the data gathering pile and is made available on an HMI somewhere. It is really cool when you perform checkout and startup without opening the laptop lid or enclosure door. (Honestly has only happened three times so far for me).
Now you have a generic driver, and can get out the prints, map the I/O, generate cross references and build the HMI app, and work out the data exchange during that process which may include copying your input map, or I may choose to use the input map user memory area as my HMI tags keeping the mapping to a minimum, while having it perfectly organized for efficient comms.
That driver code which is subdivided into sequencers, state engines or batching or process variable control logic. I have done so much coding I have templates or rough outlines of each of these to apply. With strictly ladder I also use input and output mapping for all I/O, sometimes separate HMI logic files, sometimes the mapping and I/O and HMI interfaces are part of each subsection.
If there are not too many steps and lots of branches, I tend to use state engines.
If there are a lot of steps in a relatively long discrete manufacturing machine with lots of I/O, I will consider using a sequencer with masked and sequenced input for automatic step control. This is a "style" that can turn out extremely tight code that is very flexible and can be easily tied to HMI recipes or product lists. I have only written one true sequencer for my current employer but we used them extensively on tire assembly machines where there might be more than 100 steps, and a sequencer bit width of 128 bits, with interlocking sub sequencers, and depending on the type of tire, that sequencer would need to skip groups of steps for components not needed, or apply a different number of revolutions of ply or innerliner, for example. Each step advance might be dependent of three or more of over 250 input devices, so the natural built in diagnostics of sequenced inputs make this a great way to code this style of machine.
Like Alaric, if my unconditional subroutines get too long, I tend to break them differently, but I will go several hundred rungs and make use of Advanced Diagnostics if it is best for overall structure or efficiency.
I never control real outputs in conditional subroutines. Conditional subs are fine for processing mapped data for machine control sequencers, but I reserve conditioned branching in ladder for pure functions like sorting data or complex application specific things that may be applied to an array of machines in need of the same logic and data processing.
I always assign diagnostic files for all data channels in PLC-5 and SLC50x programs.
With Red Lion, I have some button bars and master slides and a few tags that are a pretty basic template.
I have not gotten into auto code generation or made much use of library files, simply not enough time for that level of development.