<100 subscribers
Share Dialog
Share Dialog
Some time back I started to learn some p5.js to create a generative art project which I had intended to publish on ArtBlocks. The premise was simple, a basic life simulator, not unlike Conway’s game of life, but focusing more on the animation of the animal itself. The lifeform I chose to emulate was a koi fish which would swim around in a pond.
This article is meant to be a walk through the creation process.
ArtBlocks has some pretty useful code on their github docs. The code takes in a randomly generated hash string (e.g. "0x11ac128f8b54949c12d04102cf…") and uses that to seed the random number generator (RNG). The RNG is then used to define various parameters of the generative artwork.
The hardest part is starting. In order to draw a fish using nothing but native shapes, I decided to go with a circle. Lots of circles. Each time it draws a new circle, it moves 1 step to the right and draws a new slightly bigger circle. I had to play around with several formulas for the radius of the circle before I could settle on something vaguely fish shaped.

After that I manually defined several fin and tail looking shapes just to make it look a bit more like a fish. I wanted the fins and tail to be able to wiggle as the fish swims, so it was important to get the rigging set up right. The connection points between the fins / tail and the body of the fish were all manually defined by trial and error.

There were 2 animations I wanted the fish to be able to do. Swim and turn. Swimming was pretty straight forward, since it just meant redrawing the fish at position x+1 each frame. Turning would be a bit more tricky since the body of the fish would have to bend.
This was achieved by drawing each circle slightly bent away from the middle segment of the fish to generate the illusion of turning. Next, I added two parameters which defined the positional (x,y) coordinates of the fish and the angle of facing. With these in place, it is now possible to define the position and heading of each fish.

The animations were done in a simple draw loop to start, but there was still something lacking. I needed a way to govern why the fish would move the way they did. My first attempts used a random dice roll to determine when the fish would turn, and by how much - but it didn’t feel quite right.
for fish in fishes
fish.display
fish.move
if random() > 0.5
fish.turn(random())
end
Going back to the drawing board, the solution I came up with is to introduce points of interest which the fish would swim towards. Limiting their rate of turning would allow them to keep swimming towards their goal. In my mind, these points might relate to a feeding event, or perhaps just a raindrop hitting the surface of the pond would be enough to pique the interest of the fish.
I animated this as a ripple on the surface of the water. In addition, it allowed me to include a limited form of interactivity - where once every so often you would be able to “feed“ the fish by clicking on a location and the fish would (slowly) react to it.
point = random(x,y)
for fish in fishes
fish.display
fish.move
fish.turn(angleBetween(fish, point))
end
Now that we have gotten the basic fish animation down, it’s time to put the final aesthetics into place. We need a way to make each fish uniquely generated!
I adapted some code for making generative Rorschach patterns from openprocessing in order to (a) contain the pattern within the fish itself, and (b) to break the symmetry as needed.
I also created a color palette which I think best reflected the colors of Koi fish, and placed a drop shadow beneath each one to give it a more 3-dimensional feel. If you notice carefully, there are also alternative fin patterns which I built into the program as well to increase the variance.

Finally, I wanted to give the piece a bit more atmosphere - so I included some lotus leaves which could float on the top of the pond. The leaves would slowly collide and bounce off each other as they float around the pond. Here’s an easy tutorial to learn how to make something similar!
Similarly, I created several environmental palettes which would be randomly generated depending on the initial seed. There are a total of 4 environmental palettes and 4 Koi palettes which could be combined, together with the practically infinite number of body patterns on each fish.

The end piece is intended to be something you could display on your wall as a zen statement piece. The artwork is also theoretically scalable to any display size and aspect ratio, although currently it works best at 800x800 (otherwise filling the space would require rendering too many objects and slows down the animation!).

One thing I was not too satisfied with is the need to hard code in rarity tables. This stops it from being truly generative in my opinion. For example, some palettes are harder to find than others, also the number of fish generated is hard coded according to a rarity table.
I’m hoping to improve how rarities are generated in future projects. But for now, I have hard coded in an additional surprise as an “ultra-rare“ attribute. Once in a while you might spot a rare lotus flower among the leaves!

I hope you enjoyed the run through. While there currently does not exist any NFT for these, I have set up a web server (full codebase is open source under CC BY-SA3.0) as an additional utility for metajam METAPASS holders in order to showcase how NFTs allows anyone to build on each other in a completely open and permissionless manner.
The server generates the fish based on the tokenID of the METAPASS NFT(s) held in the connected wallet (in the same idea of synthetic loot). These are not NFTs, but you can play with them all the same.
Some time back I started to learn some p5.js to create a generative art project which I had intended to publish on ArtBlocks. The premise was simple, a basic life simulator, not unlike Conway’s game of life, but focusing more on the animation of the animal itself. The lifeform I chose to emulate was a koi fish which would swim around in a pond.
This article is meant to be a walk through the creation process.
ArtBlocks has some pretty useful code on their github docs. The code takes in a randomly generated hash string (e.g. "0x11ac128f8b54949c12d04102cf…") and uses that to seed the random number generator (RNG). The RNG is then used to define various parameters of the generative artwork.
The hardest part is starting. In order to draw a fish using nothing but native shapes, I decided to go with a circle. Lots of circles. Each time it draws a new circle, it moves 1 step to the right and draws a new slightly bigger circle. I had to play around with several formulas for the radius of the circle before I could settle on something vaguely fish shaped.

After that I manually defined several fin and tail looking shapes just to make it look a bit more like a fish. I wanted the fins and tail to be able to wiggle as the fish swims, so it was important to get the rigging set up right. The connection points between the fins / tail and the body of the fish were all manually defined by trial and error.

There were 2 animations I wanted the fish to be able to do. Swim and turn. Swimming was pretty straight forward, since it just meant redrawing the fish at position x+1 each frame. Turning would be a bit more tricky since the body of the fish would have to bend.
This was achieved by drawing each circle slightly bent away from the middle segment of the fish to generate the illusion of turning. Next, I added two parameters which defined the positional (x,y) coordinates of the fish and the angle of facing. With these in place, it is now possible to define the position and heading of each fish.

The animations were done in a simple draw loop to start, but there was still something lacking. I needed a way to govern why the fish would move the way they did. My first attempts used a random dice roll to determine when the fish would turn, and by how much - but it didn’t feel quite right.
for fish in fishes
fish.display
fish.move
if random() > 0.5
fish.turn(random())
end
Going back to the drawing board, the solution I came up with is to introduce points of interest which the fish would swim towards. Limiting their rate of turning would allow them to keep swimming towards their goal. In my mind, these points might relate to a feeding event, or perhaps just a raindrop hitting the surface of the pond would be enough to pique the interest of the fish.
I animated this as a ripple on the surface of the water. In addition, it allowed me to include a limited form of interactivity - where once every so often you would be able to “feed“ the fish by clicking on a location and the fish would (slowly) react to it.
point = random(x,y)
for fish in fishes
fish.display
fish.move
fish.turn(angleBetween(fish, point))
end
Now that we have gotten the basic fish animation down, it’s time to put the final aesthetics into place. We need a way to make each fish uniquely generated!
I adapted some code for making generative Rorschach patterns from openprocessing in order to (a) contain the pattern within the fish itself, and (b) to break the symmetry as needed.
I also created a color palette which I think best reflected the colors of Koi fish, and placed a drop shadow beneath each one to give it a more 3-dimensional feel. If you notice carefully, there are also alternative fin patterns which I built into the program as well to increase the variance.

Finally, I wanted to give the piece a bit more atmosphere - so I included some lotus leaves which could float on the top of the pond. The leaves would slowly collide and bounce off each other as they float around the pond. Here’s an easy tutorial to learn how to make something similar!
Similarly, I created several environmental palettes which would be randomly generated depending on the initial seed. There are a total of 4 environmental palettes and 4 Koi palettes which could be combined, together with the practically infinite number of body patterns on each fish.

The end piece is intended to be something you could display on your wall as a zen statement piece. The artwork is also theoretically scalable to any display size and aspect ratio, although currently it works best at 800x800 (otherwise filling the space would require rendering too many objects and slows down the animation!).

One thing I was not too satisfied with is the need to hard code in rarity tables. This stops it from being truly generative in my opinion. For example, some palettes are harder to find than others, also the number of fish generated is hard coded according to a rarity table.
I’m hoping to improve how rarities are generated in future projects. But for now, I have hard coded in an additional surprise as an “ultra-rare“ attribute. Once in a while you might spot a rare lotus flower among the leaves!

I hope you enjoyed the run through. While there currently does not exist any NFT for these, I have set up a web server (full codebase is open source under CC BY-SA3.0) as an additional utility for metajam METAPASS holders in order to showcase how NFTs allows anyone to build on each other in a completely open and permissionless manner.
The server generates the fish based on the tokenID of the METAPASS NFT(s) held in the connected wallet (in the same idea of synthetic loot). These are not NFTs, but you can play with them all the same.


agrimony
agrimony
No comments yet