Before starting this post-mortem, you may ask yourself : Why but why did you decide to “create a procedurally morphing billiards table” ? It’s a fair question with a simple answer.
We wanted to «open» the possibilities of French billiards (or Carambolage) without changing the core rule: with the cue ball (the white), you have to touch both coloured balls in a single shot. A perfect rule. Simple to understand, *very* hard to master.
If you don’t want to change the core rule or mess with the physics of the game, the thing that has to evolve is the table. So we created an algorithm able to draw an infinite variety of tables (we were obviously inspired by Desert Golfing here).
Morphing the table makes a lot of sense in the case of French billiards. It’s a game that relies a lot on how you collide with the sides of the table (the cushions) to gain points. Create tables with different sizes, straight angles, curved sides, pikes, gaps… and you will be able to play on slight variations of the difficulty, enough to renew the player’s experience constantly while letting him learn the skill at his own pace.
Here’s the official trailer of Magic Shot, to give you an idea:
The only constraint, a major one if you want very different sort of shapes, is that the tables needed a single «enclosed» area, so you could actually make a successful shot (without that, you may end up with a ball in one area, and another one somewhere else). That constraint was something that also brought consistency to the visual aspect of the game.
But generating a single enclosed space with enough variety is not straightforward. When you give generation methods an “x” value, they will essentially give you a “y” back. For example if x=1 -> y=0.5 ; x=2 -> y=0.6 ; x=3 -> y=0.44 … It’s a linear vision that goes well for the heightmaps of generated terrains, not for a circular enclosed space.
You need a transformation to do this, something that will tell your generation method that the “y” it gets is to draw the left side of the table, then the bottom, then the right side, then the top, depending on the “x” value.
To do that we created a “normal” rectangular table and gave for each inner points of that table an “x” value :
Then we used the “y” generated values for each « x » to pull and push the point on the line that goes from the « regular » point of the rectangular table to the center of the table. Like this :
Yes! just like a photographic Diaphragm.
That little trick gave us access to a surprisingly large variety of shapes, from Rorschach symetric stains to circles and rectangles and weird and evocative flowers. We created 13 different generators, each associated with 5 or 6 variables able to handle an infinity of shapes.
The tables shapes gain in complexity and size as you go further in the game, with a direct impact on the gameplay. The larger and more complex the shape, the more difficult the game, with strategies renewed every time.
We also used this diaphragm system to support many little details in the game, like the propagating deformation when the cue ball hits a cushion (à la The Floor is Jelly), the morphing from one table to another, the small imperfections appearing if you fail too often, and so on.
Magic Shot is an iOS game made by François Alliot and Arnaud De Bock, with the music of Renaud Bédard.