Open sourcing the Rubik's cube game

Hi folks! I’ve been working on the Rubik’s cube game in Elm using WebGL. The goal of the project was to experiment with complex user interactions and learn how to do ray tracing.

The result can be found here: https://github.com/w0rm/elm-cubik

Some of the interesting ideas in the project are:

  1. Using the same function to handle a particular message and also to conditionally subscribe to the corresponding subscription. You can find some similarities between update and subscription functions in the Main.elm.
  2. Modelling rotations as quaternions and using elm-animation library for transitions between rotations (for start game/end game transitions).
  3. Rendering text in 3D by defining a mesh as a layer of cubes, but then selectively discarding some of them in the vertex shader using the texture lookup.

Some references:

  1. If you want to implement ray tracing I recommend this post: https://medium.com/@voorkanter/clicking-a-3d-mesh-in-elm-webgl-faadfdf703a0
  2. for quaternions in Elm I basically used some parts of this library https://github.com/kfish/quaternion
  3. to create animations that just need the time from AnimationFrame subscription, I highly encourage to check https://github.com/mgold/elm-animation
15 Likes

Awesome work.

I don’t know if you have seen my ai-search library: https://github.com/the-sett/ai-search. I have recently learned how to solve the Rubiks cube myself, and would be interested in writing a solver for it in Elm. Did you already write a solver for your game? If not, I could try and contribute one to your animated cube game.

===

Although, there is an easy way to write a solver that cheats. Just record the sequence of moves made when you shuffle the cube, and then play that back in reverse order.

This is super cool!

A quick question about the WebGL package, and some of the syntax:

fragmentShader : Shader {} Uniforms {}
fragmentShader =
    [glsl|
        precision mediump float;
        uniform vec3 color;

        void main () {
          gl_FragColor = vec4(color, 1.0);
        }
    |]

So what exactly is going on in the value of this declaration? Is this valid elm syntax here? Is there a step before the Elm compiler that replaces this with something else? Or is [glsl| some kind of special Elm syntax that the compiler actually understands? Are other languages understood here? ([js| /* ... */ |], etc.).

I’ve never seen anything like this before. I didn’t see any explanation for this, so I was wondering if anyone could explain how this works. Thanks!

1 Like

You can find a little explanation at the end of the readme here; http://package.elm-lang.org/packages/elm-community/webgl/2.0.5/

This is special syntax similar to QuasiQuoters from Haskell. glsl is the only supported usage AFAIK :slightly_smiling_face:

@rupert this sounds interesting! Currently, the cube has a physical model with positions in 3d, because it is easier for rendering and interactions.

To solve it we need a way to convert it into a simpler model, solve it, and then convert it back & convert back the steps to represent them as a list of Transformation.

Let’s get in touch on Elm slack to discuss it further. I will have some time next week.

@mthadley yeah, just what @supermario said. This syntax is there only for glsl code blocks. Elm parses them using language-glsl haskell library and builds the type signature for the shader. For more information you can check my talk from Elm Europe: https://www.youtube.com/watch?v=Z-6ETEBNlMs and you can find the slides here: https://github.com/w0rm/bringing-the-fun-to-graphics-programming

So the [glsl| … |] syntax is actually built into Elm, and not by a custom | operator defined in the webgl package? Something to add to the thread on here about lesser known syntax.

1 Like

Yes, a different model is better suited to solving than rendering, I’m not sure yet what the best way of modelling for solving is, in a functional language. I’ll have some time here and there over the next few weeks, so yes to a chat on Slack.