Giter VIP home page Giter VIP logo

asteroids-arena's Introduction

asteroids-arena

The repo contains demo implementations of simple game in several languages to test their average performance, expressive power and my subjective joy of their usage.

Game concept

The game is 2D. The world is wrapped around edges. You are a triangular space ship with single engine without breaks. The ship has single gun that fires bullets. The world is filled with circular asteroids that doesn't collide with each other and collide with you. On collision with the asteroid you die. Asteroid breaks into two smaller ones on collision with bullet, but if asteroid is smaller a threshold it is destroyed. Bullets don't collide with the ship. Asteroids are randomly distributed across world on start. You win if you kill all asteroids, you loose when you die.

Important gameplay feature that bullets has relative speed to the ship when spawned, so if you shoot backward, you can get bullet that doesn't move relative to the world. There should be three supported sound effects. First, thrust sound when ship accelerates. Second, fire sound. Finally, bangs on asteroid destruction and player death. For simplicity player respawns in center of world on death.

Implementation restrictions

  • Implement entity-component-system design. If language design is not suited well for the pattern, it is acceptable to choose another design.
  • Asteroids have circloid shape and you should not memorize asteroid lines. That restriction allows to see how language backend deals with heavy load of 2D rendering (trigonometry e.x.). But you can batch all rendering calls.
  • Measure FPS of full frame with world step and rendering.
  • Use SDL for rendering.
  • Concurrency is allowed.

Languages

I am personally interested to compare some not common languages for gamedev.

Languages:

  • Haskell. My major language. The goal to test pressure of GC on performance and if it really more comfortable for game developing. Done.
  • C. Control group for performance. Done.
  • ATS2. Low level FP language with dependent typing that will allow mutation in place, redundant checks elimination and zero cost abstractions. On hold.
  • D. Curious to test it with GC and without GC. Use custom library with meta programming for boilerplate generation Done.
  • Zig. Low level alternative to pure C. Curious in performance and if it easy to bind to C libraries. Done.
  • Rust. Curious in performance and expressive power comparing to Haskell. Done.
  • С++. Widely used in game development. First implementation is unoptimized translation of C version with entt library Done.
  • OCaml. FP language with C backend, should be fast enough and with FP expression power. In Progress. Current implementation is not optimized.

Contributors

Results

Gameplay

FPS

Value Haskell C Zig Rust D C++
Max FPS 500 25000 25078 24057 27778 24494
Min FPS 3 3521 4031 2775 1376 3969
Avg FPS 115 21482 21634 19809 22559 20875
Avg to best (%) 0.5 95.23 95.90 87.81 100 92.54
Mean FPS 91 21739 21712 20695 22727 20777
FPS dispersion 87 965 970 2445 2481 1439
Dispersion % 75 4 4 12 11 7

FPS plots are built with haskell utility. Like:

cabal new-run plotting -- single fps.out
# or
cabak new-run plotting -- multiple Haskell ./fps_haskell.out Rust ./fps_rust.out Zig ./fps_zig.out

In haskell nix-shell.

FPS

Haskell

FPS now stable 40-100, smooth gameplay, but there are noticeable freezes at, possibly, major GCs. Haskell FPS

C

There is smooth gameplay. Some drops can be explained by interference of other software in OS. C FPS

Rust

Smooth gameplay. It was quite easy to implement the game and get high performance from first try.

Rust FPS

I used specs as first implementation and than rewrote to legion for more cleaner code. Amount of code and memory usage is dropped significantly. Also, I disabled legion multithreading as performance with it drops to maximum 6000 FPS as the major time game sit in work stealer inside legion schedule system. In single thread mode both ECS have near identical performance.

ECS Compare

Zig

Very stable frame rate. Feels like great upgrade over C in development experience and performance. Zig FPS

D

There are two different compilers. First, DMD is original implementation of language. Second, LDC is LLVM based implementation. DMD is usually slower than LDC, but in the particular case it's not. I have no idea why DMD generates code that is FASTER for rendering dozens of asteroids than rendering empty screen. LDC behaves like other LLVM based languages (stable constant FPS), but FPS slightly higher than the closest competitor (Zig). I implemented custom ECS in the implementation and it feels like the closest to the "production" state.

Also I used LLVM PGO (Profiling Guided Optimizations) for LDC, that makes DMD and LDC results near identical.

D FPS

C++

Based on C implementation and entt library. Implementation provided by @egorpugin.

CPP FPS

OCaml

Based on C implementation. Implementation provided by @Heimdell. FPS degrades linearly from count of ever created entities, need to be optimized further. Also, sounds are not implemented.

Ocaml FPS

Comparing to C: Ocaml FPS

Line of Code

Libraries for ECS are not included in the LoC metric unless they are not embedded in the implementation:

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               37            277            132           1529
Zig                             23            165            149           1097
Haskell                         25            157             37           1033
Rust                            23            113             74            842
D                               32            194            184            638
C++                              9             90             27            496

Line of Codes

Memory

Measured with command time -v <exe>:

Language Max memory Kb Max memory to best %
C 82760 187.29
Zig 65984 149.33
Haskell 83628 189.26
Rust 45616 103.23
D 68688 155.45
C++ 44188 100.00

Memory table

My machine

It is important that all measurements of performance are done in equal environment. So, FPS benchmarks are executed on my personal PC that has:

  • RTX 2080 Ti
  • AMD Ryzen 9 3950X
  • NixOS x86_64
  • SSD
  • 64 GiB RAM

asteroids-arena's People

Contributors

ncrashed avatar dpwiz avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.