# Nishikigoi

By [agrimony](https://paragraph.com/@agrimony-2) · 2021-11-20

---

Some time back I started to learn some p5.js to create a generative art project which I had intended to publish on [ArtBlocks](https://www.artblocks.io/). The premise was simple, a basic life simulator, not unlike Conway’s [game of life](https://en.wikipedia.org/wiki/Conway%27s_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.

Starting out
------------

ArtBlocks has some pretty useful code on their [github docs](https://github.com/ArtBlocks/artblocks-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.

Let’s make some fish
--------------------

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.

![Looks a bit wrong here...](https://storage.googleapis.com/papyrus_images/4cb62d660632d24e66f2fe48c673727cd644162a0493c2c5f343259827322a3c.png)

Looks a bit wrong here...

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.

![Now that looks more like a fish.](https://storage.googleapis.com/papyrus_images/484bcde31f602fcc4a25acf803d25c803d3d6fefe198b2171285011ee5dc8ee2.png)

Now that looks more like a fish.

Animating the fish
------------------

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.

![Testing out the turning animation.](https://storage.googleapis.com/papyrus_images/56549092d65f1d8eecce74eba7c80b6661a2d2517bd67ff69fbf4f353ef99914.gif)

Testing out the turning animation.

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
    

Making each fish unique
-----------------------

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](https://openprocessing.org/sketch/541006/) 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.

![Curated set of generated Koi fish](https://storage.googleapis.com/papyrus_images/69b0f6fadd53f10b919e2032e986ffbbd0b441b1e6639cc8b9f2c17d8922818d.png)

Curated set of generated Koi fish

Putting it all together
-----------------------

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](https://www.youtube.com/watch?time_continue=61&v=LO3Awjn_gyU&feature=emb_logo) 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.

![Snapshots of different environments and fish palettes which could be generated](https://storage.googleapis.com/papyrus_images/ae734a1a21524b2d89092f664e02200f1ef2c6676658bbd31be12a6a938afebe.png)

Snapshots of different environments and fish palettes which could be generated

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!).

![Sample output generated](https://storage.googleapis.com/papyrus_images/4c9c1f1b25927e4b4eee931d3ba439c60e26dccadf98675c63074ae684da34df.gif)

Sample output generated

Closing thoughts
----------------

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!

![A rare lotus flower has bloomed!](https://storage.googleapis.com/papyrus_images/94b0c6e11f5e94438c330314f8198d3576d320b8fe6308487d0bc4da5dda7495.png)

A rare lotus flower has bloomed!

Et Voila
--------

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](https://replit.com/@agrimony/nishikigoi-web) is open source under CC BY-SA3.0) as an additional utility for [metajam](https://metajam.asia/) 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.

[https://nishikigoi-web.agrimony.repl.co/](https://nishikigoi-web.agrimony.repl.co/)

---

*Originally published on [agrimony](https://paragraph.com/@agrimony-2/nishikigoi)*
