I was looking at TheCProject website thinking "all these professionals will have some great examples of how to set up a project in the most efficient and organized manner". I was wrong.

With this kind of code all over the net, it's obvious why people learn so many bad habits. Even the advanced open sourced projects were riddled with poor code architecture, and I know on BYOND I've only seen a few people design their codes well.

I'm as guilty as any of these people, but this year I learned of the repercussions of designing your code poorly, and now I'm even embarrassed by my old codes. The only way I was able to learn good habits was by working with a professional team on a pricey project.

So, I give these tips to anybody reading this:

1. Design your code assuming professionals will be judging it.

Make your code something to be proud of. You may need to show it to people in the future.

2. Keep your code clean, readable, and partially commented.

If it's a library or demo, people need to be able to understand it, and if it's a private code, you need to be able to understand it even after a hiatus. Also, white space is your friend.

3. Design your code modularly.

Modularity is making a set of objects mainly work within themselves (i.e. a library). It will make your code fully extensible. Most of my old codes are near impossible to edit because the modules are intertwined with each other so badly. It will also allow you to reuse your codes later on without needing to recode.

4. Separate definition from implementation.

I'm not sure how doable this is in BYOND, but when you design a contract for other objects and other versions of your program (on your computer or someone else's computer) to work with and don't change that contract later, your code is always compatible and easier to maintain. This is called writing a Schema, and it's a fundamental part of languages such as C# and XML, which are known for their great architectures.

5. Encapsulate all of your objects and consider indirect ways of accessing an object's fields/vars.

In other words, your objects should mainly only work within themselves, and only work outside of the object when fully necessary. This creates modularity within your larger modules. This is one of the reasons general programming languages use access modifiers, such as private and public.

6. Keep your fellow programmers informed on the way the code should work using access modifiers.

Access modifiers in general programming languages also tell other programmers (or yourself after a hiatus) how your code should be organized so they don't break it. For example, an abstract object is an object that can be inherited but does not contain a direct way of accessing implimentation or it does not contain an implementation. This forces programmers to inherit it instead of using it directly. Another example is making a field/var private so another programmer won't accidentally intertwine your code, making it less extensible.

7. Give small sets of fields/vars and methods/procs their own objects.

General programming languages call this a struct or structure, which have some performance perks since they are placed on the stack and not the heap. BYOND would probably take up more processing this way, but depending on the context, the organization benifits will be worth it. One great perk of doing this is the ability to pass many variables using only one parameter, and to be able to add more vars as a parameter later on without changing all the methods that use those vars. Examples of structs: A Size object with a Width var, Height var, and a Parameter() proc. A Vertex object with an X var, Y var, Z var, and a Translate() proc. As a lower-level example, a String object containing a list of Chars, a Length var, and an IndexOf() proc.

8. Program like you're trying to defeat Internet Global Warming.

This is called Green Programming; well, at least it should be. Some wankers have coined the term for hippie TV programming and open-sourced development, but I think it is a much better fit for designing your codes to use as little resources as possible. Don't keep objects in memory when they don't need to be, don't let processor-heavy algorithms run when they don't need to, and use the best methods of performing a gratuitous task (like hard deletion vs. soft deletion). Lummox JR has a great artical on this for use in BYOND, found here. I also mention this many times in my BYONDscape tutorials.

9. Program using standards.

Programming standards are a set of rules to keep your code designed strictly. They are a way of keeping everybody's codes happy amongst themselves and amongst other codes. You will see this as fundimental in web languages, but it is also important in any programming language. Sure, you could design a code in multiple ways in many languages, and it's nice to have a choice, but once your code interects with others' codes, you will wish you used only standards instead. This is the biggest reason the World Wide Web Consortium (W3C) exists.

10. Balance performance and organization.

When performance is a big issue, consider not using some of these organizational designs, but only when absolutely necessary; i.e. when it would create too much network traffic, or would use much more processing in an algorithm that already uses most of your processing. Knowing when to use these methods and when not to can be important in designing your code well. Overall, your code should mostly contain good architecture except in some small areas where performance is a major issue.

Now, great code architecture takes some time to plan out well and takes more time to write your code, but the benifits are well worth it in the end. Maybe you will spend less time coding by designing poorly in the beginning, but remember: 50% of your time or more will go towards debugging.

Good code architecture will cut down that time debugging enormously, so designing your code well will most likely save you a lot of time in the end, will save you lots of time if you want to extend your project, and will even save you a lot of time in future projects through modularity.

a professional programmer is a programmer that is never given enough time to complete their assigned tasks. if someone has to use or modify your program, they'll read your documentation, not your whole code, because its a lot faster and should convey the same thing.

write code assuming that the project will never die, and that you (or someone else) may be assigned to make modifications to it 10 years from now.

5. Encapsulize all of your objects and consider indirect ways of accessing an object's fields/vars.

simply put, make objects responsible for themselves.

i was talking to someone one day about the 3D buildings in google earth, and how cool it would be if they had every building in it. he thought it would never happen because its too much work and there's no way that google (or anyone else) could make models for all of the buildings on the planet. but, if you apply this concept of making objects responsible for themselves, its quite simple. if every person makes the model for their home and place of work, that covers almost all buildings.

of course, not all people would make those models, but that's because this isn't a computer program. we can't control real people with a simple function call (at least not yet). but the concept still works. if you make every object responsible for itself, your program can easily tackle what seems like a huge amount of work. it may seem overwhelming to implement a garbage collector and memory management system, but if you make every object responsible for itself, your job is done.

that being said, your rule #5, if explained better, could replace many of the rules on the list. for example, if objects are responsible for themselves, you wouldn't have unnecessary public variables because that could allow for other objects to take repsponsibility of your object. you also wouldn't have memory issues because each object cleans up after itself.

creating layers of abstraction like this is what makes you able to write code in C++, Java, and C# without having to know anything about machine code or assembly language. other programs worry about these things so that you don't have to. the same concept can be applied to your programs.

8. Program like you're trying to defeat Internet Global Warming.

if you want to get into optimization there's a lot more that can be said than just "don't use more memory or processor time than you need to". if you want to include a simple guideline, i'd go with something more like: if you want to optimize, focus on the bottlenecks. the rule of thumb is that 90% of the program's execution is spent in 10% of the code, so optimizing functions that aren't in this 10% will give you almost no performance gain and just make the code harder to read.

9. Program using standards.

programming standards (like the web standards) aren't standards for how to structure or write code. they are the specification of the language. they tell you how to write an interpreter for that language, not how to write a program in it. a standard about how to write code would be something like Hungarian notation.

Completely off topic, but I would love if it you would put fate back on the hub. I went to go host it a few days ago and discovered it missing.

EDIT: Also, I'm sorry but, I won't be following any programming guidelines from EA =p. I mean, they can't even grasp the concept that a game might not be running on an admin account, nevermind anything else.

its often used unnecessarily, but it is a good concept. sometimes it ruins code readability, sometimes it helps. i often use some sort of prefix notation in JavaScript because there's no compiling so there can't be compile time type checking :-)

but, a standard like this isn't a universal standard. we don't need all JavaScript developers to agree on what prefixes to use. its just something you can use on an application-by-application basis to make code a little more readable for yourself and coworkers.

I'm sure my system of naming variables and procedures would annoy a lot of people if they had to deal with it. I generally write variable names to be as long as they need to be to state the use of the variable/function (in the shortest manner that's still readable, of course). Due to that, though, I've made it a habit to make it so most people won't have to deal with those unless they are modifying the library, so I include procedures just for developers to use.

I'm not sure how doable this is in BYOND, but when you design a contract for other objects and other versions of your program (on your computer or someone else's computer) to work with and don't change that contract later, your code is always compatible and easier to maintain. This is called writing a Schema, and it's a fundimental part of languages such as C# and XML, which are known for their great architectures.

I've honestly never heard the word "Schema" used in this context, and I've never seen the word capitalised like that. Neither has Wikipedia. Your use of "contract" is a bit suspect as well; Design By Contract is not the same thing as the use of encapsulation in object-oriented design, which seems to be what you're really talking about here.

Also, "languages such as C# or XML"? WTF? XML is not a programming language. Mentioning it in the same breath as C# is misleading at best. There is such a thing as an "XML schema", but it has nothing to do with program design; it's more to do with validating XML files.

Also also, the words are spelled fundamental and implementation. =)

5. Encapsulize all of your objects and consider indirect ways of accessing an object's fields/vars.

The word is "encapsulate", Encapsulation is a useful tool, though it can be abused.

Encapsulation and data-hiding aren't specifically supported in BYOND in the same way they are in C++, Java, et al. You could, however, adopt Python's "we're all consenting adults here" approach, in which everything is public but underscores are prefixed to the names of "private" functions and variables. The underscore essentially means "don't mess with this - unless you know what you're doing".

I've honestly never heard the word "Schema" used in this context, and I've never seen the word capitalised like that. Neither has Wikipedia. Your use of "contract" is a bit suspect as well; Design By Contract is not the same thing as the use of encapsulation in object-oriented design, which seems to be what you're really talking about here.

No, schema is exactly what I meant. I used the word because it's more popular than "interface" and "contract", which all in fact refer to the same functionality. Encapsulation isn't really the same. Encapsulation is mostly refering to what OFD said, making objects responsible for themselves. Defining a contract is defining a schematic for your class so it is compatible between versions.

Also, "languages such as C# or XML"? WTF? XML is not a programming language. Mentioning it in the same breath as C# is misleading at best.

I didn't call XML a programming language. And both C# and XML use schemas, so it works just fine.

There is such a thing as an "XML schema", but it has nothing to do with program design; it's more to do with validating XML files.

C# schemas are called interfaces, and have the same function. They both validate code and define a contract in which two points interact.

Encapsulation and data-hiding aren't specifically supported in BYOND in the same way they are in C++, Java, et al. You could, however, adopt Python's "we're all consenting adults here" approach, in which everything is public but underscores are prefixed to the names of "private" functions and variables. The underscore essentially means "don't mess with this - unless you know what you're doing".

Yeah, that was either a tip for people working in another language or if they wanted to somehow support in in BYOND.

I see what you're trying to get at, but I still disagree with your word usage. I think we mostly agree on concepts, we're just quibbling over terminology.

Encapsulation isn't really the same. Encapsulation is mostly refering to what OFD said, making objects responsible for themselves.

No, I disagree. If anything, "encapsulation" is closer to your original meaning than "contract". Encapsulation is clearly defining a separation between the internal workings of a module (e.g. a class, or a bunch of classes) and the "face" that it presents to the outside world; its lines of communication, if you will. As for "contract", see below...

Defining a contract is defining a schematic for your class so it is compatible between versions.

That's only a part of it. When talking about program design, contracts usually mean the specific use of preconditions, postconditions, and usually invariants. "I, the caller, guarantee that immediately before I call this method, the following preconditions will hold." "I, the callee, guarantee that if the preconditions hold as required, then these postconditions will hold immediately as the method returns." "Both of us guarantee that these invariant conditions will hold on exit if they hold on entry."

That's why I balked at your use of the word "contract". It means something very specific, above and beyond your usage.

I didn't call XML a programming language.

Not explicitly, no, but someone who didn't know that XML wasn't a programming language could easily have guessed that you meant that C# is a programming language.

And both C# and XML use schemas, so it works just fine.

But they're different things. I guess the term schema vaguely applies in both cases, but conflating the two is a bad idea. Here's why:

XML is a way of formatting data. An XML schema is just a way of specifying an explicit element structure, and more exact formats for the data within the elements. You're merely specifying how data should be formatted.

An object-oriented design tells you nothing (or very little) about internal structure and formats. Rather, it establishes relationships, with regard to a given class, between: method calls (originally "messages", i.e. input); changes in externally-visible state; and output.

The two are similar only in a very broad sense, and I don't think the comparison is useful.

Yeah, that was either a tip for people working in another language or if they wanted to somehow support in in BYOND.

Of course. I'm just pointing out that it's not a lost cause in BYOND - the only problem is that you can't get the compiler to verify you've done it correctly, but in this case that's no big loss.

when you design a contract for other objects and other versions of your program (on your computer or someone else's computer) to work with and don't change that contract later, your code is always compatible and easier to maintain. This is called writing a Schema, and it's a fundamental part of languages such as C# and XML, which are known for their great architectures.
schema is exactly what I meant. I used the word because it's more popular than "interface" and "contract"

i'm not a stickler for terminology, but you're throwing around a lot of terms and i'm not sure what you're trying to say. however, i am sure that "schema" is not the proper term. a good rule to follow: if you understand a concept but don't know the terminology, don't worrry about terms, just explain the concept. if you understand the concept, we'll understand you.

if you're talking about establishing set interfaces that objects will use, the term is interface. that's what C# and Java call them.

if you're talking about creating and following a plan for how each class will be structured and how it will relate to other classes, you're talking about something like a class diagram.

your description for rule #4 doesn't go with what the rule is saying, and the description is not very helpful anyway.

you're saying that designing a contract and never changing it makes programming easier. if you don't need to make changes, that means you did it right the first time. its obvious that doing something right the first time is easier than doing it right the second time.

there are circumstances that you may not be able to anticipate, and you may have to make changes to the "contract". assume that change will be required. if you do, you'll see that its silly to focus on sticking to the design. what you should focus on is creating an initial design in such a way that changes are easy to make. that's not an easy task at all. you could have another list of ten guidelines for this topic alone and you'd still barely scratch the surface.

I used the word schema because an XML schema has the same purpose as a C#/Java/whatever interface. It's short for schematic, and I think the word schematic is a good word for an abstract diagram of layout and rules.

Both interfaces and schemas validate code, and they ensure compatibility.

I'm sure "class diagram" would work too, but I've never seen that term used within code so it's not really part of my vocabulary.

if you understand a concept but don't know the terminology, don't worrry about terms, just explain the concept. if you understand the concept, we'll understand you.

You're right, but I honestly can't see how I didn't communicate it well enough. As long as I'm in the same ballpark with the terminology and explain it well, I should be fine, but I thought I did explain it well.

Also, Crispy: Every single book I have read that described both XML schemas and C# interfaces has called it a "contract". If that is the wrong word, blame them :P One of my books also called C# interfaces a kind of schema. So if any of my terminology is screwed up, maybe now you can see why.

you're saying that designing a contract and never changing it makes programming easier. if you don't need to make changes, that means you did it right the first time. its obvious that doing something right the first time is easier than doing it right the second time.

there are circumstances that you may not be able to anticipate, and you may have to make changes to the "contract". assume that change will be required. if you do, you'll see that its silly to focus on sticking to the design. what you should focus on is creating an initial design in such a way that changes are easy to make. that's not an easy task at all. you could have another list of ten guidelines for this topic alone and you'd still barely scratch the surface.

I probably should have explained that more in depth. Of course you will make changes, but say for example you are trying to access a method on an object on the same program but on a different version on a different machine. Each of these programs have named the method differently. How does program A access the method on program B when it thinks program B has the same name for the method as program A? They are now incompatible, and can no longer work together.

It would be like Tom updating the BYOND Pager and you wouldn't be able to talk to people who still had the old version of the pager.

What I mean by don't change the contract, is that any changes to the contract itself could have compatibility reprocussions. However, there is a good chance you can make the changes you need to make without making your code invalid to its contract. You work around the contract to ensure compatitbility. And if you HAVE to change the contract, you will know right then and there that certain versions are incompatible, without having to test. Remember, the contract is just an understanding between a group of objects. They can change whatever they want as long as they don't change the contract.

And it's not a requirement to stick to the contract, it's just a goal. There will be a few cases where you will need to change it, but it may come at a price.

Anyways, I'm sick of arguing about using slightly off-skew terminology if it's off at all. If you want to argue, please, argue about design.

The way you communicated was confusing, at least to someone who already knew what you were trying to say, because you used the wrong words. I'm sorry, but jargon matters. If you don't know the correct words, then you can't discuss the concepts without appearing really confused.

I used the word schema because an XML schema has the same purpose as a C#/Java/whatever interface.

Except that, y'know, it totally doesn't. See my previous post that you pretty much ignored.

Also, Crispy: Every single book I have read that described both XML schemas and C# interfaces has called it a "contract". If that is the wrong word, blame them :P One of my books also called C# interfaces a kind of schema. So if any of my terminology is screwed up, maybe now you can see why.

Which books were these? I would like to know so that I can ring up the author and yell at them for being wrong.

If they merely used the word "schema" once or twice to explain the meanings of other words, then that's maybe OK. But it's a big leap from there to "This is called writing a Schema".