My first figma plugin: Metroidvanier

Emmanuele Villa

Emmanuele Villa

Simple plugin to create random rectangles to be used to build a Metroidvania level

Today I wanted to start a project for the Metroidvania Month 18 itch.io jam, and I started with the struggle of creating a world for my game.

If you are not familiar with it, Metroidvania is a genre of platform videogames focused on guided non-linearity and utility-gated exploration and progression.

For this reason, it’s essential to create a world that feels big, with rooms varying in size, so that the player doesn’t feel railroaded even if the game has a specific path.

I don’t deny my love for procedural content generation, but given the little time at my disposal a robust world-generation including passages, gates and keys would probably take the whole jam month.

But because of my lack of imagination I still wanted some assistance from a CPU to have a draft to start with.

Since I’ve used Figma to design app and games before, I’ve decided to use it also in this project. But how to receive hints for the level design? But with a Figma plugin of course!

I never created a figma plugin before, but I embarked on this adventure for the simplicity of the setup: you just need VS code, node, typescript and the Figma desktop app. Also, aside from the last, I already had everything installed!

So, once the setup is completed you will find two main files (when selecting a plugin with UI as I did):

  • ui.html, which contains the html/js code for the plugin UI, that handle user interaction and sends messages to the logic part
  • code.ts, which contains the “business logic” of the plugin, handling the message sent by the UI

In my case the plugin is very simple: a UI with a couple of settings and two buttons: create and cancel.

This is the UI (yes, I called it METROIDVANIER):

It’s composed by two parts, the first one being the (very ugly) html code:

 

				
					<h3>Create a new room:</h3>
<p>Fill color:<br />
<input type="color" id="fill_color" value="#33ff33" /><br />
Stroke color:<br />
<input type="color" id="stroke_color" value="#ffffff" /><br />
<button id="create">Create</button><br />
<button id="cancel">Cancel</button>
</p>
				
			

 

And the part that sends the message:

				
					<script defer src="data:text/javascript;base64,DQpkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3JlYXRlJykub25jbGljayA9ICgpID0+IHsNCiAgY29uc3QgZmlsbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaWxsX2NvbG9yJyk7DQogIGNvbnN0IHN0cm9rZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJva2VfY29sb3InKTsNCiAgcGFyZW50LnBvc3RNZXNzYWdlKA0KICAgIHsNCiAgICAgIHBsdWdpbk1lc3NhZ2U6IHsNCiAgICAgICAgdHlwZTogJ2NyZWF0ZS1yZWN0YW5nbGVzJywNCiAgICAgICAgZmlsbDogZmlsbC52YWx1ZSwNCiAgICAgICAgc3Ryb2tlOiBzdHJva2UudmFsdWUNCiAgICAgIH0NCiAgICB9LCAnKicpDQp9DQpkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2FuY2VsJykub25jbGljayA9ICgpID0+IHsNCiAgcGFyZW50LnBvc3RNZXNzYWdlKHsgcGx1Z2luTWVzc2FnZTogeyB0eXBlOiAnY2FuY2VsJyB9IH0sICcqJykNCn0NCg=="></script>
				
			

 

Now, we just need to handle the message in the code.ts file:

				
					figma.ui.onmessage = msg => {
  if (msg.type === 'create-rectangles') {
    console.log(msg);
    const nodes: SceneNode[] = [];
    const rect = figma.createRectangle()
    rect.x = figma.viewport.center.x;
    rect.y = figma.viewport.center.x;
    rect.resize(rand(640, 640*3), rand(360, 360*3));

    let fill = hexToRgbA(msg.fill);
    let stroke = hexToRgbA(msg.stroke);
    console.log(fill);
    console.log(stroke)

    rect.fills = [{type: 'SOLID', color: {
        r: fill[0],
        g: fill[1],
        b: fill[2]
        }}];
    rect.strokeWeight = 15;
    rect.strokeAlign = 'CENTER';
    rect.strokes = [{type: 'SOLID', color: {
        r: stroke[0],
        g: stroke[1],
        b: stroke[2]
        }}];
    figma.currentPage.appendChild(rect);
    nodes.push(rect);
    figma.currentPage.selection = nodes;
  }
};
				
			

 

This simply reads the message, creates a rectangle with some fixed properties and some read from the UI and appends it to the page in the center of the screen!

Here is an example of the plugin in action:

As you can see, the rooms are different but there is a trend of having horizontal rooms, which makes sense given the nature of the game.

The plugin is currently in review by the Figma team. Let me know if you think it’ll be useful to you and how to improve it! I’ll let you know when it is available 🙂

Share:

Facebook
Twitter
Pinterest
LinkedIn

Leave a Reply

Your email address will not be published. Required fields are marked *

On Key

Related Posts

The Renshuu Widget for Android

Are you looking for a way to keep your Renshuu study schedules front and center without constantly opening the app? The Renshuu Widget for Android might be just what you need!