17

I'm making a physics engine and its becoming quite hard to keep track of the whole thing. Often when I get back to my code after a break I just don't remember why that's not working. Most of the issues aren't simple programming mistakes but design flaws in my physics engine. That's why I should just finish designing it before programming it.

However, I need a way to write on paper the whole design of my physics engine. Else, I will just forget it tomorrow and be lost again. A UML class diagram is not appropriate at all for the design of a physics engine. I don't really care about the classes but the process. I do not see the Business process diagram as really useful because modelling a single step(frame) of my process won't help me understand the final behavior of my engine on many steps.

So, what kind of diagram should I use to help me keep track of the process ? What kind of diagram professionnals use to make a physics engine ?

  • 4
    First, I would suggest a high-level flow diagram, to show how the engine is used and how it evaluates things. Or maybe something similar to the OpenGL pipeline diagram (openglinsights.com/pipeline.html). Then, I would do a Google Images search for "Physics engine diagram" to see how other people do it! ;) – FrustratedWithFormsDesigner Jun 5 '17 at 14:00
  • 4
    By "a UML diagram" you probably mean a class diagram? Class diagram is one of 7 structural diagrams in UML. There are also 7 types of behavior diagrams. – COME FROM Jun 5 '17 at 14:34
  • First of all, you have to have a very good understanding of the physics engine; every little detail and how things work together. Nothing to do with programming. Then, you try to model it in programming entities (classes) and interactions. You can use whatever tools you like (even sketches and hand written notes). Then, you create you classes one at a time. Start by writing a console application. You can use unit/class tests to make sure that your little classes work and do what you expect – John Kouraklis Jun 5 '17 at 14:48
  • 6
    In my experience, professional programmers do not use design documents or diagrams to design things. Maybe on a whiteboard. With contemporary programming languages, designs are in the head and in the code. Design documents or diagrams are most often used for communication. Based on your description, my guess is your design needs to be decomposed. – JimmyJames Jun 5 '17 at 14:58
  • 1
    "A UML class diagram is not appropriate at all for the design of a physics engine." Why not? Classes are all about separation of concerns. Any system can be divided into components with distinct roles, and those components can usually be made into classes. – Tanner Swett Jun 5 '17 at 19:16
29

TO DO lists are wonderful things.

I'm not talking about // #TODO: blah blah comments. I mean get an honest to God notebook.

You never know when you'll remember something important to do. A notebook will quietly sit there and let you think without complaining about how your handwriting wont compile. Some of my best ideas happen in the bathroom (yes I do own a water proof notebook but you don't have to go that far).

You can get pocket sized ones that are sewn (not glued) so they don't fall apart in your pocket. Didn't manage to get a fancy one with a built in book mark? Tape, scissors, ribbon and no one will ever know.

When an idea hits just jot it down. Draw little boxes next to each idea and you can easily mark it as done. Put a box at the top of the page and you know when the page is done.

What sequential access isn't good enough for you? Yeah they make pocket binders as well. This all might seem like a bit much but it's better than drowning in post it notes or trying to capture everything in Jira.

Don't leave things half implemented

Keep your improvements small and achievable. Don't start anything that can't be finished in one sitting. If it's to big for that then break it down into smaller steps. Always leave code that compiles and passes it's tests. Oh and don't leave passing tests you've never seen fail. Making a test both pass and fail is how you test the test.

Stop thinking you need the whole design on paper

What you need to do is capture your evolving plan. You don't know how things are going to look when you're done so stop pretending you do. Capture what you have figured out as well as you can. Use a napkin and crayon if you have to. Few people understand 90% of UML anyway. Use whatever way you can to show what you need to show. I focus on showing my interfaces and what knows about what.

Write notes when you stop coding

The moment you take your fingers off the keys is the last time you will understand what you've done (and what you have planned) as well as you do now. Capture that understanding as best you can in some notes. If all you have is comments then you're still tied to the computer and likely to leave a puddle in the chair. Again, having a notebook is an awesome thing.

This way you can land your brain gracefully, save your bladder, and take off again later without resorting to caffeine and teeth gritting.

  • (As a honest notebook which is also smart, Emacs Org mode works well. A similar tool, even an an issue tracker, could work well, depending on processes. A paper notebook is great to carry around, and it allows for quick charts and pictures, which is great while thinking.) – 9000 Jun 5 '17 at 15:17
  • 6
    +1 for Don't start anything that can't be finished in one sitting. If it's to big for that then break it down into smaller steps.. It's one of the most important things I learned in industry. – Akshat Mahajan Jun 5 '17 at 18:46
8

"Everything should be built top-down, except for the first time", they say.

I'd start from the lowest level (e.g. basic vector math), and made sure I understand it well and it has a good test coverage. Then I'd build one more layer on top of that, allowing for more abstract operations (e.g. groups / entities, collision detection, collisions mechanics). Again, I'd cover it with tests; it would help me think about the real use cases of these abstractions in the engine.

Unless you have a very good understanding of the whole engine (e.g. when you re-implementing a well-known existing engine), it's usually good to have these layers; it allows you to think on a particular layer in terms of the previous layer, and usually no much deeper. You can experiment and build a layer with new useful abstractions; what proves to be practical in reality often deviates from the initial ideas.

Hopefully each layer is small enough that you don't need a complicated diagram for it, or it's easy to come up with a useful one.

I've never encountered a complex code diagram that was useful. Interaction and life cycle diagrams are useful, though. Quite often a diagram like that is constrained to 1-2 layers, and is thus simple.

What I usually find most valuable is interface descriptions and guarantees provided by each level. E.g. the format of the vector math, and what happens on numeric errors; the format of larger objects descriptions (always convex? always clockwise-oriented?, how to intersect? etc), the mechanical parameters of interaction (how time advances? how mass is handled? is momentum always preserved? how are forces calculated?) then interactions proper (how to handle friction? deformation? fragmentation? is turning of mechanical energy into heat losses a thing?).

Each layer should be small enough to have an observable amount of things it introduces and guarantees it provides. This description can even be drafted without any implementation code being written (yet). This lowers the chance to determine that you've done something horribly wrong three layers deep; if you did, it would be visible at most two layers deep already.

  • I like the building the code bottom up, making layers that become more and more expressive of your problem set. But don't think that you will get them right the first time. Once you start using a layer to implement stuff higher up, you will find problems with your API and will have to go back and change it. Its okay. – Justsalt Jun 9 '17 at 20:27
4

Make diagrams of the architecture! The OpenGL pipeline diagrams FrustratedWithFormsDesigner posted in the comments are a great example for program flow, but that’s only one type of diagram that can be useful.

When designing diagrams, you want to make understanding the code simple and intuitive; this can encompass both high-level concepts (like the top line of nodes in that OpenGL pipeline diagram, saying something) or very granular, technical details (like a full function call graph).

Ideally, your documentation should also make the code easy for other people to understand; this can make things like code reviews or open-source collaboration easy. Look to large projects to see how they accomplish this — when working with hundreds-of-thousands or millions of lines of code, understanding how the program works without having to read it is massively important for keeping track of the codebase or introducing it to others. The Vim repository, with 1.3 million LOC, has pretty great high-level documentation (IMO) for this in /src/README.txt. It introduces:

  • What code in each file does
  • Important global variables and their values
  • What happens in the main loop, and what the functions it calls
  • What happens in each of the modes, and the main functions that handle them
  • What native debugging features are

If I want to contribute a patch, I generally know which file I need to modify to accomplish my goals without much digging.

One of the best features about Vim’s /src/README.txt is how easy it is to find and how comprehensive it is; it’s not granular in any sense, but if you click the src folder on Github it automatically loads, and it gives direction for finding other code or documentation. Contrast that with the Powershell repo, which I looked to for an example but was unable to find any equivalent file or files to Vim’s /src/README.txt. (A bad sign for a project with 988 thousand LOC!)

Some things you may want to diagram or document include:

  • Conceptual program flow (What does the program accomplish, and in what order?)
  • Implemented program flow / function call graph (How does the program accomplish its goals? What functions are called or classes created?)
  • What code is in what files? What’s the organizational scheme and what rules do you have for determining where a new function goes? If you have a strong organizational scheme, knowing which file to look in for a given function or class will be easy, even without an IDE or IDE-like “find project-wide” feature.
  • Relatedly, which files include which other files (related to a function call graph)?
  • Which classes inherit from which other classes? What’s the purpose of each class?

How can you make those diagrams? At your level, and for first drafts, pencil and paper is probably the best / fastest method. When diagrams and documentation become more refined, you could look into:

  • Dot / Graphviz, a set of programs for generating graphs from .dot files.
  • LaTeX / TikZ, a very complex and verbose tool for generating graphs or pictures of any sort — it may be too hefty for your needs, especially as all node positioning is manual, but should be kept in mind, especially if you plan to write a paper or anything of that sort later.
  • For C, gson’s egypt hooks into gcc and outputs a .dot call graph. Can be automated or embedded in a make command, which is nice!
  • Relatedly, GNU cflow can generate text-only call graphs for C. Equivalent tools may exist for other languages, although you may want to stray away from automated tools in general — not creating the graph manually may hinder your understanding of the code or provide an inappropriately complex level of detail (knowing which functions call printf() is usually pretty unhelpful).
  • I'm really concerned about having good documentation but for now, I kinda stopped doing documentation because my code is constantly changing to put in place new algorithms and attempts at doing something. For example, in the code detecting continuous collision detection, I switched multiple times from storing previous positions in the Body classes to computing the previous position from the movement of the Body. This lack of professionnality is due to me designing the thing while programming because when I design something in my physics engine I want to check if it's actually possible. – Winter Jun 5 '17 at 23:12
  • I guess I should consider this project experimental and then rewrite it from scratch with the prototype I made but I put a lot of effort to make it clean enough to keep it without having to rewrite everything. – Winter Jun 5 '17 at 23:17
0

Try using a diagram based on Petri Nets. It is possible to translate the diagram in to computer programs in a systematic manner, and it is possible to integrate high-level diagrams with low-level diagrams.

References

Net Elements and Annotations: A General-Purpose Visual Programming Language (2016). Available at https://www.academia.edu/31341292/Net_Elements_and_Annotations_A_General-Purpose_Visual_Programming_Language.

Net Elements and Annotations for Computer Programming: Computations and Interactions in PDF (2014). Available at https://www.academia.edu/26906314/Net_Elements_and_Annotations_for_Computer_Programming_Computations_and_Interactions_in_PDF.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.