I'm a developer based in Paris with a Masters Degree in Computer Science and experience working in the fields of machine learning and computer graphics.
Passionate about programming, I started to learn the C programming language at 11 years old and published my first video game 5 years later. During my journey
as a curious developer, I encountered plenty of languages, softwares and tools that gave me the opportunity to learn about many concepts and to develop a wide range of skills.
My expertise
Below is a non-exhaustive list of programming languages and tools that I'm the most familiar with.
Moreover, one of the quality of a good developer is the ability to adapt and learn quickly in a new environment and technology,
and I developped this skill through a multitude of personal projects and work experiences.
AI / Machine Learning
During my studies I developed a strong interest in machine learning and artificial intelligence, so I had to learn about the most important tools to build and train neural networks.
Most of AI models are written using python for its simplicity of use and the existence of very powerful libraries and sharing tools like Jupyter Notebook or Google Colab.
I mainly use the pytorch library for my projects but I've already used tensorflow and keras. I've already trained models based on live webcam inputs thanks to OpenCV and this year I got introduced to the R functional programming language.
Web-oriented languages
I'm familiar with most of the biggest web programming languages like HTML, PHP and CSS.
Actually, they are the first languages I got familiar with when I first started programming, along with C.
I'm also really used to javascript, typescript and nodeJS that I use most often nowadays and I've built websites with ReactJS and NextJS.
Recently I've been particularly focused on web graphics and GPU computing with WebGL, three.js and processing.
Finally, I'm also familiar with Google Firebase and Amazon Web Services to implement databases, storage, authentication and different web pipelines.
Software-oriented languages
After learning C, the obvious next step was to learn C++. I programmed with these languages for most of my college years. I learned C# too through Unity projects as its the main language for scripting.
I also developped utility apps and video games for iOS using the Swift programming language and I recently made a full-stack application similar to Uber Eats using Flutter and fully integrated it to Google Firestore auth, storage and database services.
Softwares and Tools
I use git and github on a daily basis and I'm familiar with lots of design softwares.
I've already used photo editors like Photoshop and Gimp and pixel art editors like Aseprite, and I'm familiar with video production as I had a Youtube channel a few years ago and used softwares like Sony Vegas Pro, Adobe Premiere and Adobe After Effects to edit my videos.
I've made 3D rendering using Blender and 3D animations with Cinema4D, I used FL Studio to create electronic music along with Ableton Live, and finally I learned to use Unity two years ago.
Featured Projects
Neuro-Evolutive Flappy Bird
Remake of Flappy Bird in Unity played by a genetic algorithm
C#, Neural Network, Genetic Algorithm
After making my own neural network from scratch in Unity, I wanted to replace the back-propagation process using a genetic algorithm inspired by evolution and natural selection. I've remade the very simple yet famous game Flappy bird to create populations of birds that learn to avoid obstacles with these processes, and turned it into a betting game.
Neural network trained to recognize the signs for the ASL alphabet in real time
Python, Machine Learning
During my fourth year of engineering school, I made an internship at Capgemini where I had to develop a neural network architecture that could recognize the ASL alphabet. The input are the frames of a live webcam and the network makes a prediction and show the letter associated to the current sign.
Implementation of Jos Stam's "Real Time Fluid Dynamics" paper using the WebGPU API
Javascript, WebGPU, WGSL
It's been a long time since I've wanted to implement a fluid simulation algorithm, and I decided to try it out as a playground for learning the new WebGPU API that is optimized for parallel computing on the web. The code runs on GPU using WGSL compute shaders
A recursive Tic-Tac-Toe implementation with MCTS algorithm
Javascript, Machine Learning
The Ultimate Tic-Tac-Toe is a game where you play tic-tac-toe inside a bigger tic-tac-toe. This implementation let you choose the deepness of the game and allow you to play against a computer using the Monte Carlo Tree Search algorithm. This algorithm was used to defeat professionals chess and go players.
I made various generative algorithms to create digital art pieces
Javascript, WebGL, Shaders
I've always been interested in digital art and the mesmerizing pictures or animations that could be generated using the power of mathematics applied to generative algorithms. During my engineering studies, a lot of my personal projects aimed at creating beautiful visuals. In the last few months I got to talk to many digital artists who really encouraged me to continue this artistic journey.
Causality is a game about time and rewinding the flow of time. It's also a solo cooperation game, but you're cooperating with yourself... in the future ! Or in the past, it depends on the time... Inspired from the 2020 movie Tenet.
A parametizable generator for beautiful space-themed landscapes
C++, SVG
One of the projects I made during my second year in engineering school was a landscape generator. I really like space and its phenomenas so I chose this theme and started experimenting with SVG graphics. It was a fun experience both in code and in design, the render is really colorful, diversified and refined.
Adaptation of the famous mobile app on a graphical calculator
C, assembly, graphical calculator
When I was 16, I was part of a game development community focused on Casio graphical calculators. I decided to adapt the famous Jetpack Joyride mobile game on a 128x64 monochrome calculator with 1mb of memory. It resulted in a calculator app that is currently ranked as the best game on this site with more than 40,000 downloads.
An isometric puzzle game that plays around perspective and optical illusions
C, Allegro
The second project I made during my first year of engineering school was a game where the goal is to find the right sequence of movement for a robot to make in order to finish the level. The particularity of my version is that it's rendered in isometric view and uses optical illusions caused by the isometric perspective as a core mechanic in the gameplay.
During my fourth year of engineering school, I had the opportunity to make an internship inside the Fablab of Capgemini’s Applied Innovation Exchange. My final project was to build a neural network capable of recognizing the American Sign Language’s alphabet in real time through a webcam input.
All the project is made with Python 3. The main libraries that I used are :
pytorch to build and train the neural network
opencv to capture and process the webcam’s frames
mediapipe to detect hands and retrieve the position of their landmarks
mediapipe is a neural network library specialized in different body detection solutions like pose detection and face detection. I use it in order to detect hands on the frame, and it outputs a list of 21 landmarks representing the position in 3D of key points of the hand (wrist, fingers, articulations).
I then used pytorch to build the neural network that has an input size of 63 (21 landmarks * 3 dimension) and an output size of 26 (all the letters of the alphabet).
Training
I created my own dataset using a custom script capturing all the landmarks for each frame and saving them in a json file. At the end, I had 2,000 examples for each of the 26 signs for a result of 54,000 examples. After some data augmentation (vertical mirror to include left-handed people and random noise), I got to around 200,000 examples and started the training. The results of the testing loss and accuracy are shown below :
Demonstration
I made a script that use the trained model in order to predict the signs that are shown through the webcam. Multiple hands can be detected simultaneously and the prediction for each sign is shown next to it on the output frame along with the prediction confiance level.
I also added a feature that writes a sequence of signs as letters on the top left corner of the screen in order for the user to form simple words. Two ‘delete’ and ‘reset’ buttons can also be activated when a hand is detected inside their bounding box to have a better control over the sequence of letters.
An example of all of these features can be shown in the demonstration below :
Art in all its forms has always been something that I find mesmerizing and powerful and that is present in my everyday life.
I grew up in a family of artists, my mother being a poet and my grandmother being a painter sculptor. I had the chance to draw on canvas at a really young age and I’ve always been interested in the process of creation and artistic creation ever since.
During my computer science studies, I had the opportunity to discover a lot of new fields of digital art and computer-assisted art. This is when I started making my first scripts that had for unique goal to produce visually pleasing images.
At the time I didn’t really see it as art but more as fun little experimentations with sometimes complex notions like fractal, chaos or fluid mechanics producing beautiful animations.
Around a year ago through my freelancing missions, I got in contact with many digital artists who introduced me to the world of digital art generation and the concept of blockchain and who really motivated me to become an artist myself.
I realized that I could combine my two passions being art and development and use the power of computers to create algorithms generating beautiful digital art.
You can find below a list of art generators that are still in progress as I did not officialy published my first creation yet. Some of them only were ideas or experimentations and will not be officialy released.
Luminous Fantasy
This is my last creation and the one I’m actively working on. It’s the first time that I made animated art and I used the power of shaders and parallel computing on GPU to produce these results. I’m currently working on a youtube video explaining how I created this shader.
Concentricated
This is the first project I made when I discovered generative algorithms. It was inspired by the type of artwork that can be found on Artblocks and I’m planning on enhance it and publish it in the future.
A creative point
I made this generator at a time where I was just playing and experimenting with mathematicals behaviors. In this case, there is a single point that can do random (but constrained) moves between a set of points. At each move, the point can only travel a fixed percentage of the distance to the next point. By repeating this process millions of times, with different points, ratios and coloring the result by frequency, we obtain really nice geometrical shapes and fractals from a really simple set of rules !
Digital noodles
Yet another generative art experimentation exploring bezier curves. “Would you want more vegetables with your digital soup ?”
Fractal GAN
During my 2 last years of engineering school, I specialized in Artificial Intelligence and Machine Learning. One type of ML architecture is called GAN (Generative Adversarial Network) and is excellent at creating unique images mimicing the features of a specific dataset.
It’s usually used to generate faces, animals or objects but I had the idea to build a GAN that I could train on fractal images (more specifically the Mandelbrot fractal).
The results where mitigated due to a possible overfit (a lot of images turned out to be really similar) but it was definitely interesting to see what kind of images were produced by this algorithm.
As a side note, I also trained it on images of Singapore taken from a 10 hour long video of a car circulating in the streets in order to generate unique images of Singapore that don’t exist. The result is interesting (second picture).
Projects I made for independent artists
Below can be found different projects I made as a freelance for artists that wanted help to materialize their ideas in a digital form. Even if I created these algorithms they are now property of the different artists and not myself.
Anton Ginzburg
The first artist I collaborated with was Anton Ginzburg. I made a generative algorithm based on his guidelines that got exposed in the Wolfsburg Central Station in Germany. More details on Anton’s website: http://antonginzburg.com/works/public-commissions/algorithm-wob
You’re an artist and like my creations ?
If you’re an artist in the search of help concretizing an idea in a digital form, a digital artist wanting to do a collaborative work, or any artistic platform/website/event wanting to work with me for digital art creation, feel free to reach me through my social accounts as it would be a pleasure to discuss with you !
Project Review :
Neuro-Evolutive Flappy Bird
The Project
This project is a remake in Unity of the very popular game “Flappy Bird”, at the difference that it is played using a neural network made entirely from scratch in C#, with the addition of a genetic algorithm replacing the role of the back-propagation process.
Each bird belongs to a specific population and has its own neural network, which acts as its brain by deciding the next move with the informations received by its sensors.
The weights of this neural network acts as the birds’ genes and at the end of each simulation, we select and cross-over the genes of the best birds, with the introduction of random mutations like we can observe in nature and evolution to create the next populations of hopefully better-performing birds.
In the end, each of the population compete against each other to be the fastest to learn how to avoid obstacles.
Neural network from scratch
Basic Blocs
To really understand and grasp the concepts of perceptrons and neural networks, I wanted to build it starting from the most basic blocs being the maths behind it.
Thus, the first step in building this neural network was to create my own matrix library, as neural networks heavily rely on matrix operations.
This library had to handle matrices of any size and perform basic matrix operations: element-wise addition, subtraction and multiplication, transpose, inverse and dot product but also genetic operations like crossover between matrices and random mutations.
With this starting block I could tackle the task of creating a multi-layer neural network capable of handling any network architecture (any size for the input, hidden and output layers as well as any hidden layer count).
Neural Network Visualiszer
In the process, I’ve built a visualizer to better see what’s going on inside the network during the training phase.
Here is an example of such a visualization.
The first layer in green represent the input layer, the middle layers in blue are the hidden layers while the last one is the output layer.
Each line represent a connection between two neurons and the weight of the connexion is written at the start of every line. The lines are colored depending on the magnitude of their weights, from red (-1) to black (0) to green (1)
Each node represent a neuron, and the value of the node is the result of the matrix multiplication for all the connections to this node, adding its bias which is written underneath it in yellow.
In the end we can see which of the output’s neuron has the highest value (highlighted in green), being the “prediction” of the neural network based on the input values.
Final network structure
The original goal of the Flappy Bird game is to avoid hitting obstacles that are coming with more and more speed by tapping on the screen to make the bird jump. The range of actions the bird is able to do each frame is then very limited, it can either jump or not jump.
Using a standard feed-forward algorithm, we’ll be able to calculate an output value (the choice) depending on the input values and the current state of the network’s weights & biases.
To model the brain of the bird, we’ll then use a network that only has 1 output and apply a sigmoid function to it. If the result is greater than 0.5 it means that the bird should jump, otherwise the bird should do nothing.
Regarding the inputs of the network, I’ve decided to use the following values to help the bird make sense of its surroundings:
Position Difference:
First, it needs informations about the level disposition and the obstacles, so I chose to input the difference between the bird’s position and the position of the next obstacle’s center. This will give 2 values, the x-difference and the y-difference between the bird and the next obstacle.
Obstacle Size:
Each pipe has a random opening height, so it’s an important information to give to the network.
Bird Y velocity:
Next, in order to give the bird informations about its current state and speed I also input the current bird’s y velocity.
Level Global Speed:
As the bird x velocity is always 0, it didn’t make sense to include and I prefered to input the current speed of the level (which defines how fast the obstacles are moving).
Finally, I’ve played with different architectures for the hidden layers but I realized that for such a simple task there was no need to create gigantic networks, so the bird’s brain consists only of 1 hidden layer constituted of 8 nodes.
Here’s the final architecture for a birds’ brain :
Genetic Algorithm
An alternative to Back-propagation
Usually, we’ll use the classic process of feed-forward to calculate the output values along with a back-propagation algorithm to tweak the weights backwards based on the output’s error. All of this is done to train the model and improve its accuracy.
However, while this work great for tasks where we can provide the correct target data to train the network, here we don’t have a reliable way to tell if jumping or not was a good decision as the outcome can happen many frames later. The only reliable measure we have for performance is the total distance traveled by the bird, so we have to think of other ways to train and improve the model rather than using the classical approach.
Another approach to the back-propagation part, or the “learning” part, is to mimic how nature and evolution work and using the same principles to improve the model.
We’ll focus in particular on the process of natural selection, where populations of individuals who share the same genes (but different genotypes) will live and reproduce in the same environment. In this process, the individuals who lives the longer have a greater chance to reproduce and to have a descendance. Their alleles will then be advantaged in the evolution process and be more likely to be picked than the others. This way, the strongest alleles get passed to the desendance.
Crossover & Mutation
In evolution we can also find the process of crossover that can mix two genes together and the phenomenon of mutation that can slightly change a gene to the better or the worst.
Let’s implement this idea for a population of birds !
Applying it to our neural network
As each bird is associated to a neural network, we can model each bird as an individual whose alleles are the weights of its network.
We can then create a population that consists of many of these individuals that will all get assigned random alleles (or weights) at the beginning of the simulation. When every individual has lost the game, each of them gets a fitness score depending on how far they got and how many obstacles they avoided.
This will allow to create a new population of the same size where each new individual inherits alleles from two parents of the previous population, and the parents with a higher fitness score will have a greater chance of getting picked and transmitting their genotype than the others. During this process, the two parents’ genetic features will also undergo the process of crossover and mutation as mentioned earlier.
The result in action
Single population
Now instead of displaying a single bird, let’s display an entire population consisting of 600 birds playing simultaneously. I’ve made 2 modes for this simulation: the first one, that calculates the whole simulation without rendering it and detects the bird that got the furthest, and the second one that actually renders the simulation while highliting the best bird (calculated in the first mode).
At the start, every bird gets assigned random alleles (random parameters for the network weights)
Generation 1-9
We can see at the beginning that the birds are very bad and none of them really make it far before colliding with a pipe. However as the number of games increases, each generation gets a bit better and learn from the previous one.
While the first generations may have gone through by sheer luck, the latest ones seem to have learned to reposition themselves better, allowing them to go further in the game, as we can see clearly by the 10th generation :
Generation 10
In the later generation, we can clearly see the progression of the population as a larger number of individuals get through the first levels compared to the first generations.
Adding more populations
To improve the training speed, we could increase the number of birds, but instead let’s increase the number of populations to make it more fun to watch. Now there are 6 populations, each composed of 200 birds for a total of 1200 birds playing simultaneously.
At the end of each simulation, I will allow the crossover to take place between birds of different populations so that high-performing birds’ genotypes will influence all the populations (while favoring its population of origin).
Visual improvements
I assigned a different color to the highest performing bird of each population.
Moreover, I added a label on each obstacle corresponding to the highest number of birds that ever got through the obstacle. This way I had another way of keeping track of the overall improvement of the populations.
Moreover, each time the number of birds passing through an obstacle is greater than this obstacle’s highscore, an orange popup will show how much the score increased for this obstacle.
Generation 1-9
At the start like before, it’s very chaotic and none of them really gets ahead. Due to the amount of birds, more seem to be passing through but it’s still based on luck at the beginning. However, as the total number of birds is greater than with only 1 population, we can expect to observe a quicker learning rate.
Generation 10
Finally, with our new obstacle score system we can compare the amount of birds passing through the first few obstacles of each level, and we can see a clear increase meaning that the average bird gets more and more performant at flying and avoiding obstacles.
Make it fun !
The period where I was developing this project happened to be just before a week of vacation in the south of France with friends.
I thought it would be fun if I could make this experiment entertaining to play as a betting game, this is why I spent the last few days and the 6 hours of train working on fun features to add to the existing project.
Sounds
What could be better than super annoying Mario sounds played each time a bird jumps or dies ? I couldn’t think of anything so I implemented that too.
Highscore Mode
Each time a player is currently doing a highscore (in term of number of obstacles avoided), the current score will start to blink and a music will play indicating the breaking of a new record.
Replacing the birds with the heads of my friends
This was the best decision I ever made toward the entertainingness of this project.
Starting & Game Over Screens
Finally, a startup screen, a game over screen, a global statistics screen and here we have a super fun betting game including birds controled by an evolutive neural network !
Everything altogether
Browser Demo
Unity had a feature to export the project as a WebGL application so I thought it could be a great idea to make it available online as a webapp.
However, the Unity version I used still was in beta for webgl development and this project was never planned to be ran on a browser, that’s why it may be really slow or not work at all on your device, but if it does it’s pretty cool.
I’ve already tried to create a fluid simulation a few years ago using plain javascript and no GPU, but quickly came to the limitations of intense CPU computing on the web.
It’s also been some time now since I’ve wanted to learn WebGPU and I thought it would be the perfect opportunity to tackle back on implementing fluid simulation using the power of this new API optimized for parallel computing and graphic rendering.
For this simulation, I’m making use of compute shaders to do the calculations instead of fragment shaders that can be found in usual OpenGL/WebGL implementations.
The Algorithm
The algorithm is based on Jos Stam’s “Real Time Fluid Dynamics For Games” paper.
In this paper, the fluid is described as a discrete vector field representing the velocity (x and y) of the fluid at any point. At each step, the algorithm will calculate the values of the next step’s vector field based on the current one.
To do so, we make use of the Navier Strokes equations applied to incompressible fluids. This gives enough constraints to model incompressible fluids such as water.
The main steps of the algorithm are the following :
Add forces (generally at the mouse position)
Apply diffusion (the forces gradually decrease over time)
Advect the velocity field through itself (the fluid acts upon itself)
Calculate the divergence and solve the pressure equation (this is due to the fluid being incompressible)
Now in order to see things we need another field to contain the dye. This field will only go through these steps :
Add forces
Apply diffusion
Advect the dye through the velocity field
In the end it’s this field that will be displayed to the screen, not the velocity field. To make things more beautiful, the dye field is a vector field of 3 components (r, g, b) so that each color can be advected separately.
Finally, to add more details and dynamism to the fluid, we can use a technique described in the article Nvidia GPUGem’s Chapter 38 called Vorticity Confinement.
This adds a new step after the fluid at t+1 has been calculated that will calculate and increase the spinning effects at different scales.
Bonus : Running on Casio calculators
As a bonus challenge, I decided to adapt my code in C to run on old graphical calculators. This was quite a challenge as you can forgot about GPU here, there are a lot of operations that need to be done on the CPU and the clock frequency is very low, I also had memory issues that I solved by accessing extra memory directly using an unsafe pointer (that will crash one particular model of Casio!).
After days of optimizations, I managed to create a final version running at 16fps which is amazing considering all the limitations I had (my first implementation was under 1fps). You can find a demonstration below :
In 2018 I made a project for my engineering school that was a landscape generator.
The goal of this project was to become more familiar with C++, object-oriented programming and random number generators.
I’ve chosen to create a space-themed generator with a lot of properties you can tweak in order to change the generated landscape.
The program generates a .svg file that can be opened in a browser to see the result.
This extension stands for Scalable Vector Graphics and means that it can be zoomed in and out without any loss of detail, as opposite to an image file.
The generation parameters
The scene is subdivided in 4 layers :
The planet’s surface contains trees and mountains
The atmosphere is populated by spaceships and satellites
The foreground space contains all the different types of planets
The background space contains all the stars, blackholes and what I call supernovaes (that are juste brighter and bigger stars)
Layers properties
For each layer, you can modify a set of parameters specific to the elements present on the layer.
Planet Surface
Trees density
Mountains density
Trees segments : number of segments that make a tree
Atmosphere
Spaceships density
Satellites density
Flying objects height : the height at which satellites and spaceships are generated
Space foreground
Planets density
Planets size
Planets brightness : changes the halo effect around the planets that give an impression of high luminosity
Space background
Stars density and size
Supernovaes density and size
Blackholes density and size
Random seeds and number generator
For each layer, you also have an option to reset the seed used for the number generator for this specific layer, thus you can regenerate a layer independently from the other ones.
You can also enter a manual seed (represented by a number) or change the whole’s scene seed and regenerate the 4 layers to have a completely new landscape
This project is an enhancement based on the Ultimate Tic-Tac-Toe game which consists of adding a layer to the default tic-tac-toe where each of the 9 cases is a tic-tac-toe itself.
This implementation is recursive and allow for an theorically infinite number of layer. In practice, it becomes too complex for a human after the layer 3 and too slow for a computer after the layer 4.
Layers: Deepness of the recursion. (2-4) Default tic-tac-toe is 1, Ultimate tic-tac-toe is 2
Thinking time: How much time is the AI allowed to think before making a move (0.5-30)
Players: Human (waits for your click) / Random (Random AI) / Monte Carlo (ML Algorithm)
Show best move: Execute the Monte Carlo algorithm for 5 secondes but only show the best move instead of actually playing it
Reset Game: Empty all squares
Tree Explorer: See section “Monte Carlo Tree Search”
Highlight last move: Make the difference between each game state more visible while exploring the tree
How to play ?
Each small 3 × 3 tic-tac-toe board is referred to as a local board, and the larger 3 × 3 board is referred to as the global board.
The game starts with X playing wherever they want in any of the 81 empty spots. This move “sends” their opponent to its relative location. For example, if X played in the top right square of their local board, then O needs to play next in the local board at the top right of the global board. O can then play in any one of the nine available spots in that local board, each move sending X to a different local board.
If a move is played so that it is to win a local board by the rules of normal tic-tac-toe, then the entire local board is marked as a victory for the player in the global board.
Once a local board is won by a player or it is filled completely, no more moves may be played in that board. If a player is sent to such a board, then that player may play in any other board.
Game play ends when either a player wins the global board or there are no legal moves remaining, in which case the game is a draw.
Rules with more than 2 layers of recursion:
The principle is exactly the same, but the next playable zone is a bit harder to predict. For example let’s say that it’s your turn and that you can play on any of the green squares :
Where can you expect the next playable zone to be ? In order to answer this, let’s focus on the global board square containing the current playable zone. If you compare this section to the global board, you can instantly see where the next zone should be :
Now the sub-board that is going to be selected depends on the specific square you clicked on :
Finally, if the next playable zone is already won or doesn’t have any empty case, then its parent board will be selected as the playable zone instead.
For example take this move :
If the green square has already been won, then the next playable zone will be updated to this :
This process is recursive and stops at the first zone containing at least 1 playable square.
Monte Carlo Tree Search
The Monte Carlo Tree Search is a machine learning algorithm that is based on a principle of selection, expansion, simulation and back-propagation of the nodes in the tree. Each node represent a game state, and the algorithm will select the next node using a formula maintaining some balance between the exploitation of deep variants after moves with high average win rate and the exploration of moves with few simulations.
When a node is selected, the algorithm will run a random simulation starting from the current node’s game state and stopping when the game is finished (by either a win or a draw).
The result of the simulation will then be back-propagated to the parent nodes.
This process is iterated as long as the algorithm is allowed to think (by default 500ms in my implementation) and the node with the highest visit count (or the highest simulated node) will be selected as the next move.
You can then explore the generated tree with the option Tree Explorer in the settings. The first node is the current state of the board and the child represents the next possible game states. They are sorted from best to worse from left to right. You can click on any node to show its childs and explore the tree deeply.
During my years in college and high school, I was a member of a development community focused on Casio calculators named Planet Casio which is the french community of reference for Casio.
When I was 16 years old, I had the idea to create an adaptation of the worldwide famous mobile game Jetpack Joyride on a Casio graphical Calculator.
I started a changelog on the website where I could post my progress and get feedbacks and ideas to improve my game. I also became friend with some developers that helped me when I had difficulties.
It took me 3 months of development to release it to the community and it was really well-recieved : it is currently ranked as the best game of all time on the site with more than 100,000 visits on the page, 40,000 downloads and an average score of 9.65/10 for 20 reviews.
It recieved the label of quality given by the website administrators for really good games and also recieved the crush of the public award.
You can find all these informations on my game’s official page :
Coding a game on a graphical calculator comes with a lot of constraints that I saw as challenges :
The screen resolution is 128x64 pixels : Having to create a game on such a low resolution was not easy, every pixel becomes important and you need to fit a lot of objects in a relatively small game space.
The color palette is monochrome : This 2-color palette combined with a really low resolution means that it is really hard to add details to the game sprites and animations. There is a lot of work done in pixel art to find the best compromise between detail and visibility (you don’t want the game to become a big cluster of pixels that you have difficulties to recognize)
The available memory is 1Mo : I had to optimize my code so that it wouldn’t take too much memory space as it’s really valuable when the capacity is this low.
It’s a calculator : At first, these devices are not thought to have games made on them. There are a lot of technical difficulties like the refresh rate of the screen and the actual speed of the calculator which are more apparent to the PC that existed in the 90’s than supercomputers.
All of these difficulties were really interesting challenges because I was limited and had to think about every small detail to take the most out of the calculator’s power and the C programming language that I could.
Background
When I was 14 years old, I got my first graphical calculator. It was a Casio Graph 35+.
I already knew the C programming language and wanted to create my own programs on my calculator so I learned Basic Casio, which is the default language used to create programs on Casio graphical calculators.
I was happy with Basic Casio development until I learned about add-ins a few years afterwards : the calculator’s main menu is populated with various applications (Basic Calculator, Graphs, Equation Solver, Settings) and while you’re limited to 64Ko of memory when creating apps in Basic, you have another option to develop add-ins in C that appear in the main menu and have access to 1Mo memory and run globally much faster.
The problem is that you can’t develop add-ins on a Graph 35+, this option is only availabe starting from Graph 75+ (which are more powerful and expensive).
However, after some research on the internet, I learned that the software of a Graph 35+ and a Graph 75 is the same. Casio only restrain access to the full power and memory on a Graph 35+. It was quick until I found documentation and tutorials on how to flash the kernel of the Graph 35+ with the unbrideld kernel of a Graph 75.
After this step, I started to learn about add-in development and the Casio SDK and got the idea to recreate the famous Jetpack Joyride mobile app for Casio.
Project Review :
Isobot
The project
I made this project in 2017 during the first year of my engineering school. We had to make a game about controlling a character or an object using predfined movements that you had to place in the right order in order to finish a level.
The goal of this project was to become more familiar with C, pointers, and the use of the library allegro, a 2D graphics library for C that handle sprites, text and basic geometrical shapes display.
Isometric perspective
I had already made games in 2D and wanted to discover a new field while making this project, so I chose to use an isometric perspective. It’s a 2D method of rendering that enable to fake a third dimention. It is limited in some ways but it’s used in many video games, especially old ones where it was a nice way to have an impression of 3D with a limited processing power.
Also, one aspect of isometric rendering is the absence of depth: even if the brain can understand the perspective of a level in isometric view, sometimes it’s rather difficult to evaluate the distance of two objects and this can lead to optical illusions. For instance, you could see two apparently adjacent blocks and would try to walk from one to the other while they are in fact on different axis making that move impossible.
I used this exact behaviour in my game where I make those impossible moves possible so you’ll have to find the right perspective where two distant blocks touch in order to go from one to the other. This is only possible because our rendering angle is very limited in isometric view and hides the fact that the character jumps from one part of the level to another.
In this image you can see that it may seem impossible to go to the end of the level (in red) because of the gap :
But with the right perspective, it becomes possible :
Actions and goal
The availables actions are the following :
Move forward
Turn Left
Turn Right
Wait
Finish
Rotate perspective 90° left
Rotate perspective 90° right
The player will have to build a sequence using these actions and the sequence manager. Then, he can play the level and the character will execute the actions in the order chosen by the player and if it leads in the character playing the Finish action on the finishing block, the level is won.
Special features
Moving blocks
There is one type of special block that is represented by a very poorly designed arrow in Microsoft Paint. When the player steps on it, all the blocks that have the same color will move in the direction of the arrow.
This increase the complexity of some level and ask for more patience and reflexion. Here is an illustration of this bloc’s behaviour :
Multiple characters
In addition, I implemented multi-character support : while creating a level, you can setup as many character as you want (but must have the same number of finishing blocks) and the game will automatically give each character its own sequence manager and the player will have to create the right sequence for each one of them in order to finish the level :
In-game Editor
I knew that creating a 3-dimensional game rendered in 2D isometric view would make the level design difficult, so the first thing I started to do was to implement an editor that would allow me to create and edits my levels rapidly.
In this editor, there are two walls delimiting the boundaries of the back of the level, and semi-transparents lines of blocks that help locating the selection location in 3D, which can be misleading as stated above.
Also, I needed to add a special Linkage Mode for the Moving blocks. You could enter this mode while on any block in order to set it as a Linker Block and then select all the blocks that should move when the player steps on it, as well as their direction and the distance they should move :