I am not claiming to be an expert, or even know what I'm doing. However, from reverse-engineering themes and making several of my own over the past few years, I made this list of things.
If you disagree with any point, please feel free to tell me. These are just my personal notes and are by no means obligated follow them.
Comment, comment, commentLabeling sections and subsections of code is a good idea. When lots of them are strung together, all of the tags start to look the same. Labeling large sections of code is a good idea, and commenting to label viewports, sometimes even individual lines can really improve troubleshooting time. It also helps other designers coming in after you see what you did and how. If you want the theme ported, comments are always a good idea so that you will know where a line is when you need to adjust it.
Align to Nearest EdgesThis is a very useful bit of information that improves portability quite well. Generally, if a viewport is on the right half of the screen, then the x value should be negative. In the same way, if a viewport is on the bottom half of the screen, the y value should be negative. This causes that viewport to "stick" to that edge, giving it a position that is independent of screen resolution.
Use Theme Colors When PossibleThis is more subjective. If the foreground color in the .cfg of your theme is the color that you want to use for a viewport, it is a good idea not to set the colors manually. If someone wants to change text of the same color as the menu text, they should be able to change it in just one place. Same goes for background colors. If the .cfg background is already the color you want for this viewport, don't set the background manually.
Image UseAs a general rule, if an image is used more than once, it should be loaded with x and y values of 0 and displayed inside of viewports of the same size. If an image is used once, it is fine to display it in the main viewport with absolute coordinates (note that the x and y values cannot be negative). Some people choose to preload images immediately before use, others choose to preload images all at once towards the beginning of the file. If an image will be used just once (%x), then it is more portable in the code than an image that is used several times (%xl). As a general rule, if an image is going to be displayed in several different viewports, it should be declared at the top. If it is displayed only once, it is fine to load and display it in one line inside a viewport.
Image StripsImage strips are quite useful. However, it is easy to leave too much border around an image on an image strip. It is ideal to have no "empty" or background pixels along the edges of subimages in an image strip. Since cutting these will reduce all of your subimages, the pixels add up fast and can help reduce skin ram.
BackdropsKeeping backdrops free of formatting elements is a good idea. For example, making a trough for a progress bar then locks the progress bar into that particular location and makes your theme harder to port. It is best to keep formatting in the code when possible to allow elements to be dynamically scaled for easier porting and modification.
BarsSome of the main elements of a player are the progress and volume bars. These can be more complex than they seem at the outset, so code is quite important. Unless everything is displayed in the main viewport, a progress bar must be inside of a viewport.
For multiple bars in the exact same (or similar) position, one governing viewport is recommended for sizing. This would be good for themes that replace the progress bar with a volume bar on volume change. By putting both bars in a viewport and telling them to have a default width and/or height, you can adjust both bars by changing the viewport geometry (Note: in an instance where the volume bar replaces the progress bar on volume change, it should be declared after the progress bar).
For bars with a background image, it is a good idea NOT to make the background image a part of the backdrop. Like putting progress/volume combo bars in a viewport, this helps your theme be dynamically adjustable for further ports. In order to do this, display the bar background image, then the bar in the same viewport. Using the viewport to size the bar would be preferred.
LogicSince images can only be displayed after they are loaded and viewports can be called before they are loaded, it is good practice to put conditionals toward the top of the code below preloaded images.
Laying out the logic in a diagram before writing a complex conditional is a good idea. It will result in shorter, cleaner, more efficient code. Conditionals should first sorting broad categories, then getting to specific details. This will prevent redundant tags. For example, look at the following code:
%St(volume display)<%?mv<%Vd(x)|%Vd(x)%Vd(y)>|%Vd(z)>
Since these tags are difficult to read, it can be hard to spot the problem, but the %Vd(x) tag is improperly placed. Moving it outside of the %?mv conditional will optimize this code:
%St(volume display)<%Vd(x)%?mv<|%Vd(y)>|%Vd(z)>
This is a part of a process called refactoring, which looks to make code as efficient as possible. Refactoring is important because not all devices have the same processor or amount of skin ram, so when porting, your logic may be too redundant to function as expected.
None of these things are hard and fast rules, but they are somewhat ideal for writing good syntax. I will try to add as I continue to develop new themes. Please try to be nice in telling me i'm wrong.