Do's and Don'ts when developing First Project with Ignition?

I use session.custom to handle "global" variables for stuff that we use across many customers. Stuff like Hand/Off/Auto - some customers prefer different words, so session.custom is where I store those lookups, and everywhere that needs them just refers there. So 1 spot to change and it affects all the buttons/statuses etc.

Seriously consider scalability with all of your projects. You never know when something you did is going to be deployed dozens, if not hundreds of times.

One of my big projects I've worked on started out as a simple Panelview Plus > Ignition Edge update. I had heard rumors of a Cloud portion but at the time it wasn't part of my scope and we had a deadline. So I made quite a few decisions that weren't ideal at scale, but fine for a single-node Edge application running on a site by itself, providing visualization to a single PLC. Then it turned out my less-than-ideal Edge application had to scale, and run on a Cloud server, with potentially dozens and then hundreds of tenants. As it grew, the decisions I made came back to bite me, and they had to be streamlined and made scalable, especially as more and more features were asked for. Of course, with every job, I look back and have regrets and "if I knew then what I know now" moments, but it never hurts to have less of them!

At the same time, avoid the temptation to over-abstract and make everything reusable at first. I used to do this with embedded views or components for everything, components that were usable in a variety of contexts and situations, etc. And at some point I was just making more work for myself and producing a lower-performance front end. There is a balance to be sought.

The balance between YANGI and abstracting appropriately is one you only really get with experience and failure. Knowing too if the project is going to be deployed elsewhere does also help inform you on these decisions. Try to do things with best practices as best you can, keep your code readable, keep your layers separate (gui from business even in scripting) will help keep things testable and extensible for when the client says "oh wait acutally can we do this other thing way".

But experience really will be the best teacher here imo.

I don't think it has been mentioned here just yet...

When working with strings in any Jython scripts, if you ever have to format, concatenate, or involve any operation that might include a unicode codepoint, use unicode strings explicitly!

Instead of using snippets that look like this:

def my_awesome_string_tool(user_name, user_id):
    # Unicode can come from anywhere, but string encoding depends on the DB!
    notes = system.db.execScalar('getNotes', {'noteid':4})
    # The returned string may be less than ideal to work with...
    return "My user {} has these notes: {}".format(user_name, notes)

Instead, a single character change may improve outcomes:

def my_awesome_unicode_string_tool(user_name, user_id):
    # Unicode can come from anywhere, but it doesn't matter because we use unicode strings!
    notes = system.db.execScalar('getNotes', {'noteid':4})
    # The returned string is now explicitly a unicode string, and won't hurt you!
    return u"My user {} has these notes: {}".format(user_name, notes)

I've been bitten by taking unicode input and formatting it within a jython2.7 string. Don't be like me and use unicode strings!