User prompt
Add a new item. His name will be "Frost". Its rarity will be 1/8000. Link item_frost asset to Frost item.
User prompt
Add a new item. His name will be "Smoke". Its rarity will be 1/4000. Link item_smoke asset to Smoke item.
User prompt
Add a new item. His name will be "Quartz". Its rarity will be 1/2000. Link item_quartz asset to Quartz item.
User prompt
If more than one item comes out of the same item, it will accumulate in the inventory. A maximum of 64 can accumulate.
User prompt
Items we buy from Roll are not added to the inventory. Let's make all items addable to the inventory.
User prompt
Let's leave some space between the buttons.
User prompt
Let's slide the roll, collection and inventory button towards the top of the screen.
User prompt
When we press the collection button, the inventory button appears. Let's close this.
User prompt
Let's add an inventory button under the collection button. This button will be connected to roll_btn asset. Items that we cannot remove with a roll will be stored in the inventory.
User prompt
Leveling up has been very difficult. Let's reduce the number of rolls required from 100 to 50
User prompt
Let's add a level bar at the bottom of the screen. Let our level go up with every 100 rolls. Every time we level up, our luck multiplier increases.
User prompt
Add a new item. His name will be "Iron". Its rarity will be 1/1000. Link item_iron asset to Iron item.
User prompt
Let's move the chance events to the left side of the screen.
User prompt
Let's make it compatible for mobile devices
User prompt
Let's place the lucky events in a top center of the screen.
User prompt
Let's print the incoming luck events in the middle of the screen. It doesn't show up because it's off the screen.
User prompt
Let's add random luck events. These will appear on the screen at random times and last for 20 seconds. One of these events increases our chances by 10 times, and the other by 25 times.
User prompt
Add a new item. His name will be "Ash". Its rarity will be 1/512. Link item_ash asset to Ash item.
User prompt
Add a new item. His name will be "Sand". Its rarity will be 1/256. Link item_sand asset to Sand item.
User prompt
Let's add a level system. Let's level up every 100 rolls. As we level up, we're more likely to spawn rarer things. Let's create a UI for the level. Let's see how many levels we are and how much time is left to level up.
User prompt
Let's add a level system. Every time we level up, we're more likely to spawn rarer things.
User prompt
Make the transparency of everything that passes as an asset 100.
User prompt
Add a new item. His name will be "Crystal". Its rarity will be 1/128. Link item_crystal asset to Crystal item.
User prompt
Add a new item. His name will be "Moss". Its rarity will be 1/60. Link item_moss asset to Moss item.
User prompt
When we open the Collection tab, the background disappears completely. Just let the things we need to see in that tab come out
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { collection: [] }); /**** * Classes ****/ // Collection item icon (for collection view) var CollectionIcon = Container.expand(function () { var self = Container.call(this); self.asset = null; self.overlayText = null; self.setItem = function (itemDef, owned) { if (self.asset) { self.removeChild(self.asset); self.asset = null; } if (self.overlayText) { self.removeChild(self.overlayText); self.overlayText = null; } self.asset = self.attachAsset(itemDef.asset, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); self.asset.alpha = 1; if (itemDef.rotation) self.asset.rotation = itemDef.rotation; if (itemDef.overlay) { self.overlayText = new Text2(itemDef.overlay, { size: 60, fill: "#222" }); self.overlayText.anchor.set(0.5, 0.5); self.addChild(self.overlayText); } // If not owned, gray out if (!owned) self.asset.alpha = 0.25;else self.asset.alpha = 1; }; return self; }); // Item display class var ItemDisplay = Container.expand(function () { var self = Container.call(this); self.asset = null; self.overlayText = null; self.setItem = function (itemDef) { // Remove previous if (self.asset) { self.removeChild(self.asset); self.asset = null; } if (self.overlayText) { self.removeChild(self.overlayText); self.overlayText = null; } // Add shape self.asset = self.attachAsset(itemDef.asset, { anchorX: 0.5, anchorY: 0.5 }); self.asset.alpha = 1; if (itemDef.rotation) self.asset.rotation = itemDef.rotation; // Overlay text if needed if (itemDef.overlay) { self.overlayText = new Text2(itemDef.overlay, { size: 120, fill: "#222" }); self.overlayText.anchor.set(0.5, 0.5); self.addChild(self.overlayText); } }; return self; }); // Roll button class var RollButton = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('roll_btn', { anchorX: 0.5, anchorY: 0.5 }); self.bg.alpha = 1; self.label = new Text2("ROLL", { size: 70, fill: "#fff" }); self.label.anchor.set(0.5, 0.5); self.addChild(self.label); // Simple press effect self.down = function (x, y, obj) { tween(self.bg, { scaleX: 0.95, scaleY: 0.95 }, { duration: 80, easing: tween.cubicIn }); }; self.up = function (x, y, obj) { tween(self.bg, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // --- State --- /* We will use simple shapes for items (boxes, ellipses) and a "roll" button. Each item will have a unique color and shape for visual distinction. */ // We'll rotate this to look like a triangle // We'll overlay text for "star" // We'll overlay text for "hex" // Item definitions: id, name, rarity (1 in X), asset, extra (for shape/rotation/text) var ITEM_DEFS = [{ id: 0, name: "Water", rarity: 2, asset: 'item_box' }, { id: 1, name: "Stone", rarity: 3, asset: 'item_ellipse' }, { id: 2, name: "Flame", rarity: 7, asset: 'item_triangle', rotation: Math.PI / 4 }, { id: 3, name: "Breeze", rarity: 20, asset: 'item_star', overlay: "★" }, { id: 4, name: "Amber", rarity: 50, asset: 'item_hex', overlay: "⬡" }, { id: 5, name: "Moss", rarity: 60, asset: 'item_moss' }, { id: 6, name: "Crystal", rarity: 128, asset: 'item_crystal' }, { id: 7, name: "Sand", rarity: 256, asset: 'item_sand' }, { id: 8, name: "Ash", rarity: 512, asset: 'item_ash' }]; // --- Luck Event State --- var luckEventActive = false; // true if a luck event is active var luckEventMultiplier = 1; // 1 (normal), 10, or 25 var luckEventTimeout = null; // timeout id for ending event var luckEventLabel = null; // Text2 label for event var luckEventTimerBar = null; // Container for timer bar var luckEventEndTime = 0; // timestamp when event ends // Helper: Start a random luck event (10x or 25x) function startLuckEvent(multiplier) { // End any existing event endLuckEvent(); luckEventActive = true; luckEventMultiplier = multiplier; luckEventEndTime = Date.now() + 20000; // 20 seconds from now // Show label if (!luckEventLabel) { luckEventLabel = new Text2("", { size: 80, fill: 0xFFE066 }); luckEventLabel.anchor.set(0.5, 0); LK.gui.top.addChild(luckEventLabel); } luckEventLabel.visible = true; luckEventLabel.setText(multiplier === 25 ? "💎 ULTRA LUCK! 25x odds for 20s!" : "🍀 LUCKY! 10x odds for 20s!"); luckEventLabel.x = 2048 / 2; luckEventLabel.y = 80; // Move further up for mobile // Show timer bar if (!luckEventTimerBar) { luckEventTimerBar = new Container(); luckEventTimerBar.bg = LK.getAsset('item_box', { anchorX: 0, anchorY: 0 }); luckEventTimerBar.bg.width = 600; luckEventTimerBar.bg.height = 30; luckEventTimerBar.bg.alpha = 0.2; luckEventTimerBar.addChild(luckEventTimerBar.bg); luckEventTimerBar.fg = LK.getAsset('item_box', { anchorX: 0, anchorY: 0 }); luckEventTimerBar.fg.width = 600; luckEventTimerBar.fg.height = 30; luckEventTimerBar.fg.alpha = 0.7; luckEventTimerBar.fg.tint = 0xffe066; luckEventTimerBar.addChild(luckEventTimerBar.fg); LK.gui.top.addChild(luckEventTimerBar); } luckEventTimerBar.visible = true; luckEventTimerBar.x = 2048 / 2 - 300; luckEventTimerBar.y = 170; // Move up for mobile // Set timeout to end event luckEventTimeout = LK.setTimeout(function () { endLuckEvent(); }, 20000); } // Helper: End the luck event function endLuckEvent() { luckEventActive = false; luckEventMultiplier = 1; if (luckEventTimeout) { LK.clearTimeout(luckEventTimeout); luckEventTimeout = null; } if (luckEventLabel) luckEventLabel.visible = false; if (luckEventTimerBar) luckEventTimerBar.visible = false; } // Helper: Schedule the next random luck event function scheduleNextLuckEvent() { // Next event in 20-40 seconds var nextIn = 20000 + Math.random() * 20000; LK.setTimeout(function () { // 50% chance for 10x, 50% for 25x var multiplier = Math.random() < 0.5 ? 10 : 25; startLuckEvent(multiplier); // Schedule next event after this one ends LK.setTimeout(scheduleNextLuckEvent, 20000); }, nextIn); } // Start the first luck event timer scheduleNextLuckEvent(); // Helper: get item by id function getItemDef(id) { for (var i = 0; i < ITEM_DEFS.length; ++i) { if (ITEM_DEFS[i].id === id) return ITEM_DEFS[i]; } return null; } var collection = storage.collection || []; // array of owned item ids var lastRollResult = null; // id of last rolled item var rolling = false; // is animation running var showCollection = false; // --- UI Elements --- // Title var titleTxt = new Text2("Loot Roll", { size: 120, fill: "#fff" }); titleTxt.anchor.set(0.5, 0); LK.gui.top.addChild(titleTxt); // Rarity info var rarityTxt = new Text2("", { size: 60, fill: "#fff" }); rarityTxt.anchor.set(0.5, 0); LK.gui.top.addChild(rarityTxt); // Main item display var itemDisplay = new ItemDisplay(); itemDisplay.x = 2048 / 2; itemDisplay.y = 700; // Move up for mobile itemDisplay.scale.set(0.8, 0.8); // Slightly smaller for mobile game.addChild(itemDisplay); // Item name display (shows the rolled item's name) var itemNameTxt = new Text2("", { size: 80, // Slightly smaller for mobile fill: "#fff" }); itemNameTxt.anchor.set(0.5, 0); itemNameTxt.x = 2048 / 2; itemNameTxt.y = itemDisplay.y + 180; // Place below the item display, closer for mobile game.addChild(itemNameTxt); // Roll button var rollBtn = new RollButton(); rollBtn.x = 2048 / 2; rollBtn.y = 1400; // Move up for mobile rollBtn.scale.set(0.9, 0.9); // Slightly smaller for mobile game.addChild(rollBtn); // "Show Collection" button var showCollBtn = new Container(); var showCollBg = showCollBtn.attachAsset('roll_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, // Smaller for mobile scaleY: 0.6 }); showCollBg.alpha = 1; var showCollLabel = new Text2("COLLECTION", { size: 44, // Slightly smaller for mobile fill: "#fff" }); showCollLabel.anchor.set(0.5, 0.5); showCollBtn.addChild(showCollLabel); showCollBtn.x = 2048 / 2; showCollBtn.y = 1700; // Move up for mobile game.addChild(showCollBtn); // Collection view overlay var collectionOverlay = new Container(); collectionOverlay.visible = false; game.addChild(collectionOverlay); // "Back" button for collection var backBtn = new Container(); var backBg = backBtn.attachAsset('roll_btn', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.45, // Slightly smaller for mobile scaleY: 0.45 }); backBg.alpha = 1; var backLabel = new Text2("BACK", { size: 44, // Slightly smaller for mobile fill: "#fff" }); backLabel.anchor.set(0.5, 0.5); backBtn.addChild(backLabel); backBtn.x = 2048 / 2; backBtn.y = 2400; // Move up for mobile collectionOverlay.addChild(backBtn); // Collection grid var collectionIcons = []; function updateCollectionGrid() { // Remove old for (var i = 0; i < collectionIcons.length; ++i) collectionOverlay.removeChild(collectionIcons[i]); collectionIcons = []; // Layout: 3 per row, centered, smaller for mobile var perRow = 3; var spacing = 250; // Less spacing for mobile var startX = 2048 / 2 - spacing; var startY = 500; // Move up for mobile for (var i = 0; i < ITEM_DEFS.length; ++i) { var item = ITEM_DEFS[i]; var owned = collection.indexOf(item.id) !== -1; var icon = new CollectionIcon(); icon.setItem(item, owned); icon.scale.set(0.8, 0.8); // Smaller icons for mobile icon.x = startX + i % perRow * spacing; icon.y = startY + Math.floor(i / perRow) * spacing; // Name and rarity var nameTxt = new Text2(item.name, { size: 36, fill: "#fff" }); nameTxt.anchor.set(0.5, 0); nameTxt.x = 0; nameTxt.y = 90; icon.addChild(nameTxt); var rareTxt = new Text2("1 in " + item.rarity, { size: 28, fill: "#aaa" }); rareTxt.anchor.set(0.5, 0); rareTxt.x = 0; rareTxt.y = 130; icon.addChild(rareTxt); collectionOverlay.addChild(icon); collectionIcons.push(icon); } } // --- Functions --- function updateMainDisplay() { // Show last rolled item or first item var itemId = lastRollResult !== null ? lastRollResult : 0; var itemDef = getItemDef(itemId); itemDisplay.setItem(itemDef); // Show name and rarity rarityTxt.setText(itemDef.name + " • 1 in " + itemDef.rarity); // Show item name below the item display itemNameTxt.setText(itemDef.name); } function rollForItem() { // Weighted random roll, apply luck event multiplier var totalWeight = 0; for (var i = 0; i < ITEM_DEFS.length; ++i) { var rarity = ITEM_DEFS[i].rarity; // Apply multiplier: only to rarest item (lowest odds, highest rarity) var effectiveRarity = rarity; if (luckEventActive && i === ITEM_DEFS.length - 1) { effectiveRarity = Math.max(1, Math.floor(rarity / luckEventMultiplier)); } totalWeight += 1 / effectiveRarity; } var r = Math.random() * totalWeight; var acc = 0; for (var i = 0; i < ITEM_DEFS.length; ++i) { var rarity = ITEM_DEFS[i].rarity; var effectiveRarity = rarity; if (luckEventActive && i === ITEM_DEFS.length - 1) { effectiveRarity = Math.max(1, Math.floor(rarity / luckEventMultiplier)); } acc += 1 / effectiveRarity; if (r <= acc) return ITEM_DEFS[i].id; } return ITEM_DEFS[ITEM_DEFS.length - 1].id; } function animateRoll(resultId) { rolling = true; // Flash through random items, then land on result var flashes = 12; var flashTime = 60; var i = 0; function flashNext() { if (i < flashes) { var fakeId = Math.floor(Math.random() * ITEM_DEFS.length); itemDisplay.setItem(getItemDef(fakeId)); ++i; LK.setTimeout(flashNext, flashTime); } else { // Land on result itemDisplay.setItem(getItemDef(resultId)); // Animate scale itemDisplay.scale.set(1.2, 1.2); tween(itemDisplay, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.bounceOut }); rolling = false; updateMainDisplay(); } } flashNext(); } // --- Event Handlers --- // Roll button rollBtn.down = function (x, y, obj) { if (rolling || showCollection) return; // Call the original RollButton.down (the class method), not this event handler if (typeof RollButton.prototype.down === "function") { RollButton.prototype.down.call(rollBtn, x, y, obj); } }; rollBtn.up = function (x, y, obj) { if (rolling || showCollection) return; // Do roll var resultId = rollForItem(); lastRollResult = resultId; // Add to collection if new if (collection.indexOf(resultId) === -1) { collection.push(resultId); storage.collection = collection; } animateRoll(resultId); updateMainDisplay(); // Call the original RollButton.up (the class method), not this event handler if (typeof RollButton.prototype.up === "function") { RollButton.prototype.up.call(rollBtn, x, y, obj); } }; // Show collection showCollBtn.down = function (x, y, obj) { if (rolling) return; showCollBg.scaleX = 0.95; showCollBg.scaleY = 0.95; }; showCollBtn.up = function (x, y, obj) { if (rolling) return; showCollBg.scaleX = 1; showCollBg.scaleY = 1; showCollection = true; collectionOverlay.visible = true; updateCollectionGrid(); // Hide main UI elements when collection is open titleTxt.visible = false; rarityTxt.visible = false; itemDisplay.visible = false; itemNameTxt.visible = false; rollBtn.visible = false; showCollBtn.visible = false; }; // Back from collection backBtn.down = function (x, y, obj) { backBg.scaleX = 0.95; backBg.scaleY = 0.95; }; backBtn.up = function (x, y, obj) { backBg.scaleX = 1; backBg.scaleY = 1; showCollection = false; collectionOverlay.visible = false; // Restore main UI elements when leaving collection titleTxt.visible = true; rarityTxt.visible = true; itemDisplay.visible = true; itemNameTxt.visible = true; rollBtn.visible = true; showCollBtn.visible = true; }; // --- Initial State --- updateMainDisplay(); collectionOverlay.visible = false; // --- GUI Layout --- titleTxt.x = 2048 / 2; titleTxt.y = 30; // Slightly higher for mobile rarityTxt.x = 2048 / 2; rarityTxt.y = 140; // Move up for mobile // --- Touch Handling (prevent drag) --- game.move = function (x, y, obj) {}; game.down = function (x, y, obj) {}; game.up = function (x, y, obj) {}; // --- Game Update --- game.update = function () { // Update luck event timer bar if active if (luckEventActive && luckEventTimerBar && luckEventTimerBar.visible) { var now = Date.now(); var total = 20000; var left = Math.max(0, luckEventEndTime - now); var frac = left / total; luckEventTimerBar.fg.width = 600 * frac; if (left <= 0) { endLuckEvent(); } } };
===================================================================
--- original.js
+++ change.js
@@ -207,9 +207,9 @@
}
luckEventLabel.visible = true;
luckEventLabel.setText(multiplier === 25 ? "💎 ULTRA LUCK! 25x odds for 20s!" : "🍀 LUCKY! 10x odds for 20s!");
luckEventLabel.x = 2048 / 2;
- luckEventLabel.y = 120; // Move to top center, below title
+ luckEventLabel.y = 80; // Move further up for mobile
// Show timer bar
if (!luckEventTimerBar) {
luckEventTimerBar = new Container();
luckEventTimerBar.bg = LK.getAsset('item_box', {
@@ -232,9 +232,9 @@
LK.gui.top.addChild(luckEventTimerBar);
}
luckEventTimerBar.visible = true;
luckEventTimerBar.x = 2048 / 2 - 300;
- luckEventTimerBar.y = 220; // Move to just below the label
+ luckEventTimerBar.y = 170; // Move up for mobile
// Set timeout to end event
luckEventTimeout = LK.setTimeout(function () {
endLuckEvent();
}, 20000);
@@ -292,41 +292,46 @@
LK.gui.top.addChild(rarityTxt);
// Main item display
var itemDisplay = new ItemDisplay();
itemDisplay.x = 2048 / 2;
-itemDisplay.y = 900;
+itemDisplay.y = 700; // Move up for mobile
+itemDisplay.scale.set(0.8, 0.8); // Slightly smaller for mobile
game.addChild(itemDisplay);
// Item name display (shows the rolled item's name)
var itemNameTxt = new Text2("", {
- size: 90,
+ size: 80,
+ // Slightly smaller for mobile
fill: "#fff"
});
itemNameTxt.anchor.set(0.5, 0);
itemNameTxt.x = 2048 / 2;
-itemNameTxt.y = itemDisplay.y + 220; // Place below the item display
+itemNameTxt.y = itemDisplay.y + 180; // Place below the item display, closer for mobile
game.addChild(itemNameTxt);
// Roll button
var rollBtn = new RollButton();
rollBtn.x = 2048 / 2;
-rollBtn.y = 1800;
+rollBtn.y = 1400; // Move up for mobile
+rollBtn.scale.set(0.9, 0.9); // Slightly smaller for mobile
game.addChild(rollBtn);
// "Show Collection" button
var showCollBtn = new Container();
var showCollBg = showCollBtn.attachAsset('roll_btn', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 0.7,
- scaleY: 0.7
+ scaleX: 0.6,
+ // Smaller for mobile
+ scaleY: 0.6
});
showCollBg.alpha = 1;
var showCollLabel = new Text2("COLLECTION", {
- size: 48,
+ size: 44,
+ // Slightly smaller for mobile
fill: "#fff"
});
showCollLabel.anchor.set(0.5, 0.5);
showCollBtn.addChild(showCollLabel);
showCollBtn.x = 2048 / 2;
-showCollBtn.y = 2050;
+showCollBtn.y = 1700; // Move up for mobile
game.addChild(showCollBtn);
// Collection view overlay
var collectionOverlay = new Container();
collectionOverlay.visible = false;
@@ -335,37 +340,40 @@
var backBtn = new Container();
var backBg = backBtn.attachAsset('roll_btn', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 0.5,
- scaleY: 0.5
+ scaleX: 0.45,
+ // Slightly smaller for mobile
+ scaleY: 0.45
});
backBg.alpha = 1;
var backLabel = new Text2("BACK", {
- size: 48,
+ size: 44,
+ // Slightly smaller for mobile
fill: "#fff"
});
backLabel.anchor.set(0.5, 0.5);
backBtn.addChild(backLabel);
backBtn.x = 2048 / 2;
-backBtn.y = 2500;
+backBtn.y = 2400; // Move up for mobile
collectionOverlay.addChild(backBtn);
// Collection grid
var collectionIcons = [];
function updateCollectionGrid() {
// Remove old
for (var i = 0; i < collectionIcons.length; ++i) collectionOverlay.removeChild(collectionIcons[i]);
collectionIcons = [];
- // Layout: 3 per row, centered
+ // Layout: 3 per row, centered, smaller for mobile
var perRow = 3;
- var spacing = 320;
+ var spacing = 250; // Less spacing for mobile
var startX = 2048 / 2 - spacing;
- var startY = 600;
+ var startY = 500; // Move up for mobile
for (var i = 0; i < ITEM_DEFS.length; ++i) {
var item = ITEM_DEFS[i];
var owned = collection.indexOf(item.id) !== -1;
var icon = new CollectionIcon();
icon.setItem(item, owned);
+ icon.scale.set(0.8, 0.8); // Smaller icons for mobile
icon.x = startX + i % perRow * spacing;
icon.y = startY + Math.floor(i / perRow) * spacing;
// Name and rarity
var nameTxt = new Text2(item.name, {
@@ -523,11 +531,11 @@
updateMainDisplay();
collectionOverlay.visible = false;
// --- GUI Layout ---
titleTxt.x = 2048 / 2;
-titleTxt.y = 40;
+titleTxt.y = 30; // Slightly higher for mobile
rarityTxt.x = 2048 / 2;
-rarityTxt.y = 200;
+rarityTxt.y = 140; // Move up for mobile
// --- Touch Handling (prevent drag) ---
game.move = function (x, y, obj) {};
game.down = function (x, y, obj) {};
game.up = function (x, y, obj) {};
Water. In-Game asset. 2d. High contrast. No shadows
Stone. In-Game asset. 2d. High contrast. No shadows
Flame. In-Game asset. 2d. High contrast. No shadows
Breeze. In-Game asset. 2d. High contrast. No shadows
Ember. In-Game asset. 2d. High contrast. No shadows
light green moss. In-Game asset. 2d. High contrast. No shadows
Crystal. In-Game asset. 2d. High contrast. No shadows
sand. In-Game asset. 2d. High contrast. No shadows
Gray ash. In-Game asset. 2d. High contrast. No shadows
Iron bar. In-Game asset. 2d. High contrast. No shadows
Rectangular button. In-Game asset. 2d. High contrast. No shadows
Quartz. In-Game asset. 2d. High contrast. No shadows
smoke. In-Game asset. 2d. High contrast. No shadows
Frozen human. In-Game asset. 2d. High contrast. No shadows
Thunder. In-Game asset. 2d. High contrast. No shadows
Vine. In-Game asset. 2d. High contrast. No shadows
spark. In-Game asset. 2d. High contrast. No shadows
lucky pebble. In-Game asset. 2d. High contrast. No shadows
Fortune Leaf. In-Game asset. 2d. High contrast. No shadows