Tangled Game v1.0.0

I created a de-tangle game in Ada and Rust (for comparison) using Raylib.

9 Likes

Doesn’t build:

$ git clone https://github.com/nerdtype/tangled/
Cloning into 'tangled'...
remote: Enumerating objects: 29, done.
remote: Counting objects: 100% (29/29), done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 29 (delta 1), reused 29 (delta 1), pack-reused 0 (from 0)
Receiving objects: 100% (29/29), 187.70 KiB | 5.36 MiB/s, done.
Resolving deltas: 100% (1/1), done.
$ cd tangled/ada
$ alr build
ⓘ Deploying gnat_native=13.2.2...
################################################################################################################################################### 100.0%
ⓘ gnat_native=13.2.2 installed successfully.
ⓘ Deploying raylib=0.1.0...
Cloning into '/home/laguest/.local/share/alire/releases/alr-tcdn.tmp'...
remote: Enumerating objects: 145, done.
remote: Counting objects: 100% (145/145), done.
remote: Compressing objects: 100% (81/81), done.
remote: Total 145 (delta 66), reused 123 (delta 48), pack-reused 0 (from 0)
Receiving objects: 100% (145/145), 6.86 MiB | 37.75 MiB/s, done.
Resolving deltas: 100% (66/66), done.
Submodule 'raygui' (https://github.com/raysan5/raygui.git) registered for path 'raygui'
Cloning into '/home/laguest/.local/share/alire/releases/alr-tcdn.tmp/raygui'...
remote: Enumerating objects: 6449, done.        
remote: Counting objects: 100% (1248/1248), done.        
remote: Compressing objects: 100% (307/307), done.        
remote: Total 6449 (delta 931), reused 1015 (delta 879), pack-reused 5201 (from 1)        
Receiving objects: 100% (6449/6449), 11.36 MiB | 36.81 MiB/s, done.
Resolving deltas: 100% (3456/3456), done.
Submodule path 'raygui': checked out '25c8c65a6e5f0f4d4b564a0343861898c6f2778b'
warning: unable to rmdir 'raygui': Directory not empty
Submodule 'raylib' (https://github.com/raysan5/raylib.git) registered for path 'raylib'
Cloning into '/home/laguest/.local/share/alire/releases/alr-tcdn.tmp/raylib'...
Submodule path 'raylib': checked out '30781c423b38405544c2880f15789a07f3f1e3ca'
ⓘ Found 1 nested crate in /home/laguest/.local/share/alire/releases/raylib_0.1.0_d5a6702e:
   examples/examples=0.1.0-dev: Examples for Raylib-ada
ⓘ Building tangled=0.1.0-dev/tangled.gpr...                                                                              
Setup
   [mkdir]        object directory for project Raylib
   [mkdir]        library directory for project Raylib
   [mkdir]        object directory for project Tangled
   [mkdir]        exec directory for project Tangled
Compile
   [Ada]          tangled.adb
   [Ada]          raylib_config.ads
   [Ada]          raylib.ads
tangled.adb:51:33: error: "Sound" not declared in "Raylib"
tangled.adb:157:28: error: "SetSoundVolume" not declared in "Raylib"
tangled.adb:158:28: error: "PlaySound" not declared in "Raylib"
tangled.adb:247:34: error: "LoadSoundFromWave" not declared in "Raylib"

   compilation of tangled.adb failed

gprbuild: *** compilation phase failed
error: Command ["gprbuild", "-s", "-j0", "-p", "-P", "/tmp/tangled/ada/tangled.gpr"] exited with code 4
error: Compilation failed.

Works with raylib 1.0.1.

Same here, but different error (On Windows 11, alire 2.0.1). Why does it want to use gnat_native 13.2.2 BTW? I already have gnat_native=14.1.3 in use:

Note: Deploying gnat_native=13.2.2...
############################################################################################################################################################################# 100.0%
Warning: tar failed: Command ["tar", "-x", "-f", "C:\Users\paezj\AppData\Local\alire\cache\toolchains\alr-iqsi.tmp\gnat-x86_64-linux-13.2.0-2.tar.gz"] exited with code128 and output: /usr/bin/tar: Cannot connect to C: resolve failed
ERROR: Deployment of binary archive gnat-x86_64-linux-13.2.0-2.tar.gz at https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnat-13.2.0-2/gnat-x86_64-linux-13.2.0-2.tar.gz with hash sha256:a27fd7945ac9ead50abdd8e4564d133d00f635536bf9dfdf1e00af5e08a0c494 to C:\Users\paezj\AppData\Local\alire\cache\toolchains\gnat_native_13.2.2_a27fd794 failed```

Nice little game :+1:

PS: The Raylib dependency is not correct, I opened a merge request: Update Raylib dependency in alire.toml by Fabien-Chouteau · Pull Request #1 · nerdtype/tangled · GitHub

1 Like

It’s trying to get a linux compiler. Can you show us the result of alr show --graph?

Sure, here it is, largely the same result though :thinking:

PS C:\work\ada\tangled\ada> alr show --graph
Note: Deploying gnat_native=13.2.2...
############################################################################################################################################################################# 100.0%
Warning: tar failed: Command ["tar", "-x", "-f", "C:\Users\paezj\AppData\Local\alire\cache\toolchains\alr-twnh.tmp\gnat-x86_64-linux-13.2.0-2.tar.gz"] exited with code128 and output: /usr/bin/tar: Cannot connect to C: resolve failed
ERROR: Deployment of binary archive gnat-x86_64-linux-13.2.0-2.tar.gz at https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnat-13.2.0-2/gnat-x86_64-linux-13.2.0-2.tar.gz with hash sha256:a27fd7945ac9ead50abdd8e4564d133d00f635536bf9dfdf1e00af5e08a0c494 to C:\Users\paezj\AppData\Local\alire\cache\toolchains\gnat_native_13.2.2_a27fd794 failed
PS C:\work\ada\tangled\ada>```

It should look like this:

$ alr show --graph
tangled=0.1.0-dev: Untangle game using Raylib
Origin: path /tmp/tangled/ada
Properties:
   Author: Nerd-Type
   Description: Untangle game using Raylib
   License: MIT
   Name: tangled
   Tag: game
   Version: 0.1.0-dev
   Website: 
Dependencies (direct):
   raylib=1.0.1
Dependencies (graph):
Cannot find required tool: EASY_GRAPH
warn: Alire is not able to install tool: 'EASY_GRAPH'
Defaulting to tree view.
tangled=0.1.0-dev
└── raylib=1.0.1 (=1.0.1)
    ├── gnat=14.2.1 (gnat_native) (>=12 & <2000)
    └── libraylib^5 (indirect,hinted) (^5)
Dependencies cannot be met

Any thoughts on comparing / contrasting how it went in Ada and Rust?

In my case it just trying to deploy gnat_native=13.2.2 again, and failing. I can’t get it to show the dependency graph :roll_eyes:
I’m on Windows 11, alire 2.0.1.

Here’s a difference:

$ cargo run
    Updating crates.io index
  Downloaded bitflags v2.6.0
  Downloaded autocfg v1.3.0
  Downloaded tuple_utils v0.3.0
  Downloaded ahash v0.3.8
  Downloaded specs-derive v0.4.1
  Downloaded byteorder v1.5.0
  Downloaded home v0.5.9
  Downloaded arrayvec v0.5.2
  Downloaded shlex v1.3.0
  Downloaded lazy_static v1.5.0
  Downloaded shrev v1.1.3
  Downloaded maybe-uninit v2.0.0
  Downloaded glob v0.3.1
  Downloaded either v1.13.0
  Downloaded rand_chacha v0.3.1
  Downloaded ppv-lite86 v0.2.20
  Downloaded mopa v0.2.2
  Downloaded cmake v0.1.50
  Downloaded cexpr v0.6.0
  Downloaded cfg-if v1.0.0
  Downloaded tynm v0.1.10
  Downloaded crossbeam-queue v0.2.3
  Downloaded rand_core v0.6.4
  Downloaded rustc-hash v1.1.0
  Downloaded scopeguard v1.2.0
  Downloaded which v4.4.2
  Downloaded lazycell v1.3.0
  Downloaded hibitset v0.6.4
  Downloaded cfg-if v0.1.10
  Downloaded getrandom v0.2.15
  Downloaded quote v1.0.36
  Downloaded errno v0.3.9
  Downloaded lock_api v0.4.12
  Downloaded parking_lot_core v0.9.10
  Downloaded crossbeam-utils v0.7.2
  Downloaded libloading v0.8.5
  Downloaded fs_extra v1.3.0
  Downloaded smallvec v1.13.2
  Downloaded shred v0.10.2
  Downloaded unicode-ident v1.0.12
  Downloaded clang-sys v1.8.1
  Downloaded zerocopy-derive v0.7.35
  Downloaded parking_lot v0.12.3
  Downloaded proc-macro2 v1.0.86
  Downloaded log v0.4.22
  Downloaded prettyplease v0.2.20
  Downloaded hashbrown v0.7.2
  Downloaded raylib v5.0.1
  Downloaded cc v1.1.6
  Downloaded rand v0.8.5
  Downloaded minimal-lexical v0.2.1
  Downloaded memchr v2.7.4
  Downloaded nom v7.1.3
  Downloaded specs v0.16.1
  Downloaded zerocopy v0.7.35
  Downloaded itertools v0.12.1
  Downloaded aho-corasick v1.1.3
  Downloaded bindgen v0.69.4
  Downloaded syn v1.0.109
  Downloaded regex v1.10.5
  Downloaded syn v2.0.72
  Downloaded regex-syntax v0.8.4
  Downloaded rustix v0.38.34
  Downloaded regex-automata v0.4.7
  Downloaded libc v0.2.155
  Downloaded linux-raw-sys v0.4.14
  Downloaded raylib-sys v5.0.0
  Downloaded 67 crates (9.7 MB) in 0.87s (largest was `raylib-sys` at 2.5 MB)
   Compiling proc-macro2 v1.0.86
   Compiling unicode-ident v1.0.12
   Compiling autocfg v1.3.0
   Compiling cfg-if v1.0.0
   Compiling libc v0.2.155
   Compiling glob v0.3.1
   Compiling prettyplease v0.2.20
   Compiling lazy_static v1.5.0
   Compiling rustix v0.38.34
   Compiling linux-raw-sys v0.4.14
   Compiling bitflags v2.6.0
   Compiling regex-syntax v0.8.4
   Compiling minimal-lexical v0.2.1
   Compiling clang-sys v1.8.1
   Compiling either v1.13.0
   Compiling memchr v2.7.4
   Compiling libloading v0.8.5
   Compiling quote v1.0.36
   Compiling log v0.4.22
   Compiling syn v2.0.72
   Compiling nom v7.1.3
   Compiling home v0.5.9
   Compiling bindgen v0.69.4
   Compiling itertools v0.12.1
   Compiling crossbeam-utils v0.7.2
   Compiling hashbrown v0.7.2
   Compiling rustc-hash v1.1.0
   Compiling lazycell v1.3.0
   Compiling smallvec v1.13.2
   Compiling regex-automata v0.4.7
   Compiling which v4.4.2
   Compiling cc v1.1.6
   Compiling shlex v1.3.0
   Compiling maybe-uninit v2.0.0
   Compiling cexpr v0.6.0
   Compiling lock_api v0.4.12
   Compiling cmake v0.1.50
   Compiling fs_extra v1.3.0
   Compiling regex v1.10.5
   Compiling cfg-if v0.1.10
   Compiling syn v1.0.109
   Compiling parking_lot_core v0.9.10
   Compiling ahash v0.3.8
   Compiling byteorder v1.5.0
   Compiling getrandom v0.2.15
   Compiling scopeguard v1.2.0
   Compiling arrayvec v0.5.2
   Compiling mopa v0.2.2
   Compiling crossbeam-queue v0.2.3
   Compiling rand_core v0.6.4
   Compiling shrev v1.1.3
   Compiling hibitset v0.6.4
   Compiling tynm v0.1.10
   Compiling tuple_utils v0.3.0
   Compiling parking_lot v0.12.3
   Compiling shred v0.10.2
   Compiling specs v0.16.1
   Compiling zerocopy-derive v0.7.35
   Compiling specs-derive v0.4.1
   Compiling zerocopy v0.7.35
   Compiling ppv-lite86 v0.2.20
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.5
   Compiling raylib-sys v5.0.0
   Compiling raylib v5.0.1
   Compiling tangled v0.1.0 (/tmp/tangled/rust)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 39.66s
     Running `target/debug/tangled`

and

$ alr with
Dependencies (direct):
   raylib=1.0.1

$ alr build
warn: Generating possibly incomplete configuration because of missing dependencies
◷ Syncing build dir... warn: Generating possibly incomplete environment because of missing dependencies
ⓘ Building tangled=0.1.0-dev/tangled.gpr...                                
Compile
   [Ada]          tangled.adb
   [C]            raygui_impl.c
   [Ada]          raylib_config.ads
   [Ada]          raylib.adb
   [Ada]          raylib-gui.adb
raylib-gui.adb:5:07: warning: possible aliasing problem for type "C_String_Array_Access" [enabled by default]
raylib-gui.adb:5:07: warning: use -fno-strict-aliasing switch for references [enabled by default]
raylib-gui.adb:5:07: warning: or use "pragma No_Strict_Aliasing (C_String_Array_Access);" [enabled by default]
tangled.adb:179:14: warning: procedure "Draw_Ball" is not referenced [-gnatwu]
Build Libraries
   [gprlib]       RaylibAda.lexch
   [archive]      libRaylibAda.a
   [index]        libRaylibAda.a
Bind
   [gprbind]      tangled.bexch
   [Ada]          tangled.ali
Link
   [link]         tangled.adb
✓ Build finished successfully in 2.33 seconds.

Merged. Thanks Fabien.

Aha! Pulling the last change by Fabien has fixed it for me. I would like to know what was wrong though…

Nice game!

The alr show --graph:

PS C:\work\ada\tangled\ada> alr show --graph
tangled=0.1.0-dev: Untangle game using Raylib
Origin: path C:\work\ada\tangled\ada
Properties:
   Author: Nerd-Type
   Description: Untangle game using Raylib
   License: MIT
   Name: tangled
   Tag: game
   Version: 0.1.0-dev
   Website:
Dependencies (direct):
   raylib~1.0.1
Dependencies (graph):
Cannot find required tool: EASY_GRAPH
Warning: Alire is not able to install tool: 'EASY_GRAPH'
Defaulting to tree view.
tangled=0.1.0-dev
+-- raylib=1.0.1 (~1.0.1)
    +-- gnat=14.1.3 (gnat_native) (>=12 & <2000)
    +-- libraylib=5.0.0 (^5)```
1 Like

The only changes were to the raylib dependency it looks like: Update Raylib dependency in alire.toml by Fabien-Chouteau · Pull Request #1 · nerdtype/tangled · GitHub

Maybe the old raylib had a specific dependency?

1 Like

Thoughts on Rust:

I found the borrow checker to be quite annoying and I don’t care for the syntax overall. Converting a number to a C string was somewhat tricky. I am not sure why it is necessary to have a ‘const’ keyword when there is the ‘mut’ keyword.

Differences:

I was surprised to find out that Rust and Ada do not have the same ‘for’ loop control behavior:

For instance, in Ada a loop from 1 to 5 is:

for Index in 1 .. 5 loop
  do_something;
end loop;

In Rust, this is:

for Index in 1 .. 5 + 1
{
  do_something();
}

As others have pointed out, the Ada version compiles much faster than the Rust version.

:+1:

You’re probably aware of this, but const means the value is known at compile time. An immutable value is not necessarily known at compile time. The upshot is that a const value should be determined at compile time, and an error reported if that doesn’t happen. So it’s different from Ada’s constant, which is more along the lines of an immutable value in Rust. I imagine that feature flags and macros would want to know this, though I can’t think of any examples off the top of my head.

I’m not familiar enough with Ada to know if its compilers figure out automatically whether a constant can be determined at compile time, and if so, proceed appropriately.

Why would that surprise you? I also dislike it, but it’s rather common (Python comes to mind rather painfully at the moment – I was going to add Kotlin and Nim, but they are surprisingly sane).

PS really cool game. is there a way to determine the minimum number of moves necessary? it would be nice to compare how one does

1 Like

I can confirm this, but I also notice that the Ada version fails to compile if an earlier version of raylib is not installed on the system already; I had to alr upgrade and then it prompted me to install it through the system’s package installer. The Rust version always (after a cargo clean) downloads its own version regardless, and runs cmake on it. So the time comparison is blown significantly out of proportion by a compile of C/C++ source.

One big need that it address was with compile time generics. A few years ago, you couldn’t provide array bounds to a generic in Rust due to the lack of allowing const parameters in generics. I was using nightly to make bounded containers for a long time waiting on that feature to make it into the language.

1 Like

The ARM uses the term static, which is roughly equivalent to known at compile time (though there are some surprising exceptions).

1 Like

Thanks. I had sort-of been hoping that constant arrays or records might be static, but apparently not (strings aside).