MATCHA CLIENT

A better cup of Java.

Matcha Client is a fully open source, modern Minecraft PvP modpack that features plenty of mods and only free cosmetics.

package matchaclient.client.mod.mods;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import matchaclient.client.mod.config.Setting;
import matchaclient.client.render.font.Fonts;
import matchaclient.client.render.font.MatchaFontRenderer;
import matchaclient.client.mod.hud.HudMod;
import matchaclient.client.render.Draw;
import matchaclient.client.render.MatchaColor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;

import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;

/**
 * Displays the movement keys, and optionally the mouse buttons, lighting up as they are used.
 *
 * <p>Keys are placed on a grid: WASD occupies the familiar two rows, with the mouse buttons
 * and space bar added below when enabled.
 */
public final class KeystrokesMod extends HudMod {
	@Setting(id = "key_size", name = "Key Size", min = 12d, max = 48d, order = 1)
	public float keySize = 22f;

	@Setting(id = "gap", name = "Gap", min = 0d, max = 12d, order = 2)
	public float gap = 2f;

	@Setting(id = "corner_radius", name = "Corner Radius", min = 0d, max = 12d, order = 3)
	public float cornerRadius = 4f;

	@Setting(id = "show_mouse", name = "Show Mouse Buttons", order = 4)
	public boolean showMouse = true;

	@Setting(id = "show_space", name = "Show Space Bar", order = 5)
	public boolean showSpace = true;

	@Setting(id = "show_cps", name = "Show CPS On Mouse Keys", visibleIf = "show_mouse", order = 6)
	public boolean showCps = true;

	@Setting(id = "background", name = "Key Background", order = 10)
	public Color background = new Color(0, 0, 0, 120);

	@Setting(id = "background_pressed", name = "Key Background (Pressed)", order = 11)
	public Color backgroundPressed = new Color(255, 255, 255, 190);

	@Setting(id = "text_color", name = "Key Text", order = 12)
	public Color textColor = Color.WHITE;

	@Setting(id = "text_color_pressed", name = "Key Text (Pressed)", order = 13)
	public Color textColorPressed = new Color(16, 16, 16);

	/** Click timestamps for the CPS readout on the mouse keys. */
	private final List<Long> leftClicks = new ArrayList<>();
	private final List<Long> rightClicks = new ArrayList<>();

	private boolean leftWasDown;
	private boolean rightWasDown;

	public KeystrokesMod() {
		super("keystrokes", "Keystrokes", "Shows the keys you are pressing", 0.02d, 0.55d);
	}

	@Override
	public void onTick() {
		if (!this.showCps) return;

		boolean leftDown = Mouse.isButtonDown(0);
		boolean rightDown = Mouse.isButtonDown(1);

		if (leftDown && !this.leftWasDown) this.leftClicks.add(System.currentTimeMillis());
		if (rightDown && !this.rightWasDown) this.rightClicks.add(System.currentTimeMillis());

		this.leftWasDown = leftDown;
		this.rightWasDown = rightDown;

		long cutoff = System.currentTimeMillis() - 1000L;
		this.leftClicks.removeIf(time -> time < cutoff);
		this.rightClicks.removeIf(time -> time < cutoff);
	}

	@Override
	public void render() {
		draw(false);
	}

	/** Draws with every key lit, so the element is easy to see while positioning. */
	public void renderEditorPreview() {
		draw(true);
	}

	/**
	 * The block's size follows only the key size, gap and which optional rows are on -- all
	 * settings, so it can be derived without drawing.
	 */
	@Override
	protected void measure() {
		float step = this.keySize + this.gap;

		this.width = this.keySize * 3f + this.gap * 2f;
		this.height = rowCount() * step - this.gap;
	}

	/**
	 * Height of the block in rows, counting the fractional row the shorter space bar occupies.
	 * Shared with {@link #draw} so the measured and drawn heights cannot disagree.
	 */
	private float rowCount() {
		// WASD always takes two rows.
		float rows = 2f;

		if (this.showMouse) rows += 1f;

		if (this.showSpace) {
			// The space bar is drawn shorter than a full key, so it adds less than a whole row.
			rows += (this.keySize * 0.55f) / (this.keySize + this.gap);
		}

		return rows;
	}

	private void draw(boolean forceLit) {
		GameSettings settings = Minecraft.getMinecraft().gameSettings;
		float step = this.keySize + this.gap;

		// Row 0: forward. Row 1: left, back, right.
		key(settings.keyBindForward, step, 0f, 1, 0, 1, forceLit);
		key(settings.keyBindLeft, step, 0f, 0, 1, 1, forceLit);
		key(settings.keyBindBack, step, 0f, 1, 1, 1, forceLit);
		key(settings.keyBindRight, step, 0f, 2, 1, 1, forceLit);

		float rows = 2f;

		if (this.showMouse) {
			drawMouseKey(0, step, rows, forceLit);
			drawMouseKey(1, step, rows, forceLit);
			rows += 1f;
		}

		if (this.showSpace) {
			// The space bar spans the full width and is drawn shorter than a normal key.
			float y = rows * step;
			float width = this.keySize * 3f + this.gap * 2f;
			float height = this.keySize * 0.55f;

			boolean pressed = forceLit || settings.keyBindJump.isKeyDown();

			Draw.roundedRect(0f, y, width, height, this.cornerRadius, colorFor(pressed));

			MatchaFontRenderer font = Fonts.small;

			if (font != null) {
				font.drawCenteredBoth("____", width / 2f, y + height / 2f, textFor(pressed));
			}
		}

		// Sized through the same helper measure() uses, so the two always agree.
		measure();
	}

	private void drawMouseKey(int button, float step, float row, boolean forceLit) {
		boolean pressed = forceLit || Mouse.isButtonDown(button);

		// Each mouse key is one and a half cells wide, so the pair fills the WASD width.
		float width = (this.keySize * 3f + this.gap * 2f - this.gap) / 2f;
		float x = button * (width + this.gap);
		float y = row * step;

		Draw.roundedRect(x, y, width, this.keySize, this.cornerRadius, colorFor(pressed));

		MatchaFontRenderer font = Fonts.small;

		if (font == null) return;

		String label;

		if (this.showCps) {
			int count = button == 0 ? this.leftClicks.size() : this.rightClicks.size();
			label = count + " CPS";
		} else {
			label = button == 0 ? "LMB" : "RMB";
		}

		font.drawCenteredBoth(label, x + width / 2f, y + this.keySize / 2f, textFor(pressed));
	}

	private void key(KeyBinding binding, float step, float originY, int column, int row, int span,
					 boolean forceLit) {
		boolean pressed = forceLit || binding.isKeyDown();

		float x = column * step;
		float y = originY + row * step;
		float width = this.keySize * span + this.gap * (span - 1);

		Draw.roundedRect(x, y, width, this.keySize, this.cornerRadius, colorFor(pressed));

		MatchaFontRenderer font = Fonts.medium;

		if (font == null) return;

		font.drawCenteredBoth(labelOf(binding), x + width / 2f, y + this.keySize / 2f, textFor(pressed));
	}

	/** Single-character label where possible, since a key box is narrow. */
	private String labelOf(KeyBinding binding) {
		String name = Keyboard.getKeyName(binding.getKeyCode());

		return name == null ? "?" : name;
	}

	private MatchaColor colorFor(boolean pressed) {
		return MatchaColor.of(pressed ? this.backgroundPressed : this.background);
	}

	private MatchaColor textFor(boolean pressed) {
		return MatchaColor.of(pressed ? this.textColorPressed : this.textColor);
	}
}

Not your normal cup of tea.

Matcha Client is fundamentally different from other Minecraft clients.

This one is see-through.

Every line of code is open source, meaning you can add your own features, cosmetics, and more.

Brewed with your favorite mods.

Frames, ping, clicks, coordinates, armour, potions. The ones you'd actually switch on.

Garnish it to make it yours.

Pick mods up, drop them where you want. Snap to the edges or what's already there.

Whatever is your cup of tea.

Size, spacing, what each one shows. Every mod opens up, and every change happens while you watch.

Call Matcha performative.

It's not an insult to us. We're performative like that.

All cosmetics.
On the house.

No store, no tiers, nothing to unlock. Somebody made these for fun and now they're yours.

Made one?
Send it over.

Draw something good and it goes in the client with your name next to it. Add a cosmetic →

  • Amber Checker cape

    Amber Checker

  • Amber Crimson cape

    Amber Crimson

  • Azure Gradient cape

    Azure Gradient

  • Checker cape

    Checker

  • Corner Fade cape

    Corner Fade

  • Crimson Fade cape

    Crimson Fade

  • Cross cape

    Cross

  • Diagonal cape

    Diagonal

  • Diamond cape

    Diamond

  • Dither cape

    Dither

  • Dots cape

    Dots

  • Framed cape

    Framed

  • H Stripes cape

    H Stripes

  • Leaf cape

    Leaf

  • Line Pattern cape

    Line Pattern

  • Matcha Fade cape

    Matcha Fade

  • Nested cape

    Nested

  • Noise cape

    Noise

  • Radial cape

    Radial

  • Seam cape

    Seam

  • Slate Fade cape

    Slate Fade

  • Spiral cape

    Spiral

  • Split Vert cape

    Split Vert

  • Starfield cape

    Starfield

  • Stripes cape

    Stripes

  • Vert Stripes cape

    Vert Stripes

  • Violet Fade cape

    Violet Fade

  • Wave H cape

    Wave H

  • Wave cape

    Wave

  • Amber Checker cape

    Amber Checker

  • Amber Crimson cape

    Amber Crimson

  • Azure Gradient cape

    Azure Gradient

  • Checker cape

    Checker

  • Corner Fade cape

    Corner Fade

  • Crimson Fade cape

    Crimson Fade

  • Cross cape

    Cross

  • Diagonal cape

    Diagonal

  • Diamond cape

    Diamond

  • Dither cape

    Dither

  • Dots cape

    Dots

  • Framed cape

    Framed

  • H Stripes cape

    H Stripes

  • Leaf cape

    Leaf

  • Line Pattern cape

    Line Pattern

  • Matcha Fade cape

    Matcha Fade

  • Nested cape

    Nested

  • Noise cape

    Noise

  • Radial cape

    Radial

  • Seam cape

    Seam

  • Slate Fade cape

    Slate Fade

  • Spiral cape

    Spiral

  • Split Vert cape

    Split Vert

  • Starfield cape

    Starfield

  • Stripes cape

    Stripes

  • Vert Stripes cape

    Vert Stripes

  • Violet Fade cape

    Violet Fade

  • Wave H cape

    Wave H

  • Wave cape

    Wave

  • Amber Checker cape

    Amber Checker

  • Amber Crimson cape

    Amber Crimson

  • Azure Gradient cape

    Azure Gradient

  • Checker cape

    Checker

  • Corner Fade cape

    Corner Fade

  • Crimson Fade cape

    Crimson Fade

  • Cross cape

    Cross

  • Diagonal cape

    Diagonal

  • Diamond cape

    Diamond

  • Dither cape

    Dither

  • Dots cape

    Dots

  • Framed cape

    Framed

  • H Stripes cape

    H Stripes

  • Leaf cape

    Leaf

  • Line Pattern cape

    Line Pattern

  • Matcha Fade cape

    Matcha Fade

  • Nested cape

    Nested

  • Noise cape

    Noise

  • Radial cape

    Radial

  • Seam cape

    Seam

  • Slate Fade cape

    Slate Fade

  • Spiral cape

    Spiral

  • Split Vert cape

    Split Vert

  • Starfield cape

    Starfield

  • Stripes cape

    Stripes

  • Vert Stripes cape

    Vert Stripes

  • Violet Fade cape

    Violet Fade

  • Wave H cape

    Wave H

  • Wave cape

    Wave

Install Matcha in a minute.

  1. 1Choose your settings.
  2. 2Click install.
  3. 3Open Minecraft.

Available for Windows, macOS and Linux.

Go on, take a sip!

Free now, free later, free forever.

Download
  • Windows
  • macOS
  • Linux

Your computer will probably warn you about an unknown publisher. That's because we haven't paid for a signing certificate, not because anything's wrong! If you don't trust us,have a look at the code for yourself.