I have a dilemma here, I always know that softcoded means that it is easier to maintain and make edits to my code if it ever breaks, and that I can have parameters deal with everything. However in my game that I am making it requires so much checks, in this constructor it would take in 8 arguments(timetick,fretnumber,string,type,etc...).
It is especially hard since doing checks like these and apply/create them would slow down the current thread and needs to be in time with the music.
I then hardcoded it in so that there were more different functions that takes less arguments, but there were too much and it required a parser to read the table and convert them to be created. I have no experience with code design. In my case, what parts should be hardcoded/softcoded?
Some points:
One of the most useful guidelines is "DRY" - Don't Repeat Yourself. So long as you aren't repeating yourself, you can get a lot further than if you have repeated code everywhere (since then you only need to make changes to one place).
As Color3fromRGB says, you may benefit from looking into Lua objects or by looking up Object Oriented Programming (OOP). There are numerous best practices (for OOP and for coding in general) that you can look into (ex here: https://www.quora.com/What-are-some-good-coding-practices-a-developer-needs-to-follow, though some aren't as relevant to Roblox)
"In my case, what parts should be hardcoded/softcoded?"
In general, anything you expect might change in the future and anything that is easy to softcode should be softcoded. For example: * Always assigning a literal number to a variable and refer to the variable; this enables you to easily change it in a single place later (and also makes it easier to understand -- "50" means less than "NotesPerSong", for instance)
Though you probably aren't anywhere near this point, I've recently fallen into sort of the "opposite" trap: writing functions before I've actually repeated myself (trying to save time); I usually end up with functions that do the wrong thing (ie they work for the first case, but not the second). This can be avoided by waiting until you have an actual instance of repetition before writing a function or class for it.