https://subdomain.itch.io

Godot submissions

  • Out of control, 2020
  • Joined together, 2021
  • Roll of the dice, 2022
  • Role reversal, 2023
  • Built to Scale, 2024
https://subdomain.itch.io

Issues with Godot

  • GDScript (~Python) makes me not want to write code
  • 2020: Fiddling with Node2D physics tree, chain of joints unstable
  • 2024: Theme=built to-scale, Godot doesn't support dynamic scaling.
  • Bloat (40mb empty game)
https://blog.logrocket.com/5-rust-game-engines-consider-next-project/

Let's use Rust! 😇😈

Image

"Bevy is a simple, data-driven game engine."

Let's use D!

❤️ to Godot and Rust

My D + WebAssembly history

# Run `nix-shell` to use this development environment, 'exit' quit, 'nix-shell --run $SHELL' to update
with import <nixpkgs> {};
mkShell {
  buildInputs = [

    # Dependencies of the executable
    alsa-lib    # Kernel-level audio
    libGL       # Graphics
    pulseaudio  # Desktop manager-level audio
    xorg.libX11 # Window creation, input reading

    # Tools for building
    dmd        # build development builds
    ldc        # build release builds
    esbuild    # to minify javascript
    lld        # for wasm-ld
    wabt       # for wasm-strip
    gnumake    # make
    dub        # dub

    # Running a local HTTP server for WebAssembly
    python3
    pkgs.python3
    pkgs.python3Packages.websockets
    # Submitting to itch
    butler     # uploading to itch.io

    # The better shell (has zsh auto completions!)
    zsh

    # language servers
    serve-d  # D
    nil      # nix

    # Misc utilities
    git
    qoi        # convert images to qoi
    imagemagick_light # convert images
    ffmpeg     # convert audio
    lsof       # for testing if the local server is running
    coreutils  # for nohup, etc.
  ];
    shellHook = ''
    export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${lib.makeLibraryPath [ libGL pulseaudio xorg.libX11 ]}"
    exec zsh  # Automatically switch to zsh
  '';
}

Tech stack

  • object.d: custom WASM runtime (1000 lines, https://github.com/adamdruppe/webassembly)
  • glfw-d: Windows/X11 window/input
  • libsoundio-d: WASAPI / PulseAudio sound
  • opengl.d: OpenGL bindings/utils (600 lines)
  • webgl.js/gamecanvas.js glue (600 lines)
  • collision.d: SAT / ray cast (300 lines)
class Room {
    Entity[] entities;
}

class Entity 
{
    Vec3 position;

    void create();
    void step(); // fixed time step
    void draw(ref Mesh mesh);
    void drawGui(ref Mesh mesh);
}

class Player : Entity 
{
    override step() {...}
}

Assets

Issues

  • code-d / Sublime on NixOS
  • Engine developed as we go
  • JavaScript setInterval(..., 1000/60) = 45 fps on Firefox + power saving
  • requestAnimationFrame(loop) timer aliasing
/// Hack to make i"" strings work, which import core.interpolation which references this symbol
pragma(mangle, "_D4core13interpolation16__getEmptyStringFNaNbNiNfZAya")
public string __getEmptyString() @nogc pure nothrow @safe => "";

Issues

Image

https://dennis0.itch.io/