I have implemented an N-body simulation using the Barnes-Hut optimisation in Python which runs at a not-unacceptable speed for N=10,000 bodies, but it's still too slow to watch real time.

A new frame is generated each time-step, and to display the frame we must first calculate the new positions of the bodies, and then draw them all. For N=10,000, it takes about 5 seconds to generate one frame (this is waaay too high as Barnes-Hut should be giving better results). The display is done through the pygame module.

I would thus like to record my simulation and replay it once after it's done at a higher speed.

How can I accomplish this without slowing down the program or exceeding memory limitations?

One potential solution is simply to save the pygame screen each timestep, but this is apparently very slow.

I thought also about storing the list of positions of the bodies generated each time step, and then redrawing all the frames once the situation finishes. Drawing a frame still takes some time, but not as much time as it takes to calculate the new positions.

  • 2
    $\begingroup$ TBH, the time needed to save out an image file is insignificant compared to 5 seconds. So, I'd just save out the images and stitch them together into a video later, if that's the easiest thing to do. Another possibility is to stream the frames out to ffmpeg (answer is for C++, but the same idea should be adaptable to Python). $\endgroup$ Sep 27, 2017 at 1:19
  • $\begingroup$ @NathanReed You should post that as an answer. $\endgroup$
    – Dan Hulme
    Sep 27, 2017 at 10:14
  • $\begingroup$ Possible duplicate of OpenGL animation - turn into mp4 movie $\endgroup$ Sep 27, 2017 at 18:55
  • $\begingroup$ @DanHulme TBH, I think this question can probably be marked as a dupe of the one I linked. :) $\endgroup$ Sep 27, 2017 at 18:55
  • 1
    $\begingroup$ @NathanReed I'm inclined not. The other question seems to be about turning an apitrace recording into a video. That doesn't have the same concern about keeping a fixed time-step. Also, this questioner has some misconceptions about performance, which need addressing directly. $\endgroup$
    – Dan Hulme
    Sep 28, 2017 at 7:28

2 Answers 2


user1118321's suggestion is the correct one but i'll elaborate a bit.

You run your simulation giving it a fixed time step between frames. This time step would be 1/30th of a second (33.3333 ms) for instance if you wanted a 30 fps movie.

You let your simulation calculations and your rendering run, taking as long as they need to, and then write the rendered frame out to disk, with the frame number in the name (like frame0.bmp, frame1.bmp, etc).

After you have all these frames, you can use ffmpeg to combine them into a video of the desired frame rate.

If you want audio in your video (like sounds when things collide), you can actually keep an audio timeline (what audio events happened on which frames, or at what points in time) while doing your simulation, and then after your rendering is finished, you can generate the audio stream that goes along with your video, which ffmpeg will gladly combine with your video.

I've used this on a few projects in times past and it's worked great. I also wrote up some more details about this process a while back:

Recording lagless demo videos of a laggy game | The blog at the bottom of the sea


You could always write each frame out as an image and then use another tool to compress it into a movie that you playback. You don't say what type of system you're running on, but I believe that ffmpeg could do it for you, as it's a cross-platform tool. It's hard to estimate how long the compression will take since it will depend on the content you're compressing. I'm not sure whether you can continuously feed it frames, or if you need to generate them all at once.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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