??, an emoji adventure
October 7, 2019 6:13 PM   Subscribe

??, an emoji adventure
πŸ‰ is a tiny emoji-based adventure game I made for the latest Ludum Dare game jam, built out of Javascript, HTML, CSS, and the game's internal emoji-based scripting language.

The game is built around a simple rewriting system for emoji, each operation replacing some collection of emoji with others, with the player and the game together making choices of which legal operations to perform based on the symbols available. As such systems are Turing-complete, I was able to implement a game engine out of these rewrite rules, featuring exploration, turn-based combat, and leveling up. I made things easier for myself by creating shorthand codes for commonly useful operations (for example, "πŸ₯šπŸ”πŸ£" means "replace πŸ₯š with 🐣 as many times as possible"). I also made something like an event system whereby rules can be grouped with a tag: "β–ΆπŸ”œ" means "perform all currently-legal operations tagged with πŸ”œ". As an example, the "damage" emoji is πŸ’”, and it's associated with the rule "πŸ†•:πŸ’”β€βž‘πŸ–€", meaning "immediately after creating a πŸ’”, perform the substitution 'replace πŸ’”β€ with πŸ–€' once."
Role: designer and programmer
posted by NMcCoy (6 comments total) 1 user marked this as a favorite

This is cool. But I can't for the life of me work out how to solve the level ❻ goal of 🧭:πŸ™πŸ•πŸœπŸ–πŸ°πŸ”... any chance of a hint?
posted by avapoet at 4:09 AM on October 8, 2019


...at least I managed to fall in love (also: πŸ”ž) with a πŸ‰. That's a kind of winning, right? ;-)

This was a lot of fun. I love the concepts in the scripting language too.
posted by avapoet at 4:33 AM on October 8, 2019


Congrats on the Good Ending. ❻ is, right now, the level cap; "🧭:πŸ™πŸ•πŸœπŸ–πŸ°πŸ”" is just the thing that opens all the locations when you click on the map (triggering the 🧭 event).
posted by NMcCoy at 4:55 PM on October 8, 2019


(Also I just noticed that the game's name got digested into question marks in the post title; the perils of being a pretentious indie game dev, I suppose.)
posted by NMcCoy at 4:58 PM on October 8, 2019 [1 favorite]


Crossposted from my comment on the game's Ludum Dare page, in response to someone being curious as to how it was implemented:

All the source code is embedded in the html file, though not really documented or anything (I was kinda making it up as I went so there's some questionable design decisions), so to summarize:
The core of the game consists of a dictionary serving as the "emoji pool", tracking the count of each emoji in play, and a dictionary mapping emoji->the "rules" associated with the emoji. Each rule is structured as "event:operation", the operation usually being a substitution effect (indicated with ➑) but sometimes a shorthand (e.g., bare emoji without one of my specially handled "verb" emoji is a shorthand for "replace nothing with these"). Hovering over an emoji lists all the rules that could currently be executed if the appropriate event were triggered (or all the rules if hints are enabled); clicking on an emoji fires the πŸ‘† event on that emoji, executing all the πŸ‘† rules on it. πŸ‘† and πŸ†• are the only events explicitly invoked by the Javascript framework, all others are triggered "in-engine" by the β–Ά verb-emoji. When this happens, the framework iterates over all non-zero-count emoji in the pool and executes the appropriate rules on each of them, a number of times equal to the count for that emoji.
In terms of presentation, I set it up so that there's a couple divs in the page that "request" specific emojis from the pool in a given order using a data-value in their tag; the "render" function first checks for the requests made by the page, grabbing those emoji from a temporary copy of the pool and allocating them, then puts all the remaining non-requested emoji in the main centered div. (There were a lot of visual bugs in testing, like when I forgot to add πŸ₯Ύ to the inventory requests so they hung around in the main pool div instead.) Usable buttons (those with at least one πŸ‘† event that could legally be executed) are given an extra class when being written to the html of the page, which the CSS then gives an eye-catching rainbow-animated background to.
Figuring out how to have the emoji game engine track if the player was in combat/had defeated all foes was tricky; I didn't implement a categorization system, so all the combatant emoji had to have a rule where they responded to an event to indicate that they were still alive, and a rule that removed them when the player fled combat. Halfway through development, I made a helper function that I could give a list of "these emoji are combatants" and it would append those two rules to the dictionary's rules for that emoji, saving me a lot of further repetitive emoji-typing. The ⚠ emoji signifies that the player is in combat; the ⚠:⚠ rule that the combatants all have means "when the ⚠ event fires, add a ⚠ emoji to the pool" as an indicator of "hey, I'm still alive". The defeat rule for each combatant looks like "πŸ‘†:πŸ’₯πŸ’₯πŸ’₯πŸ¦ˆβž‘β­β­βœ”" -- when clicked, trade 3 damage emojis and a shark for 2 experience points and a check mark, if such a trade is possible. The βœ” has a πŸ†• event that removes all ⚠, fires the ⚠ event to ask if anyone's still around, makes a πŸ—Ί if there aren't any ⚠ in the pool after that, then replaces itself with nothing. In hindsight there may have been a cleaner way to do it, but I think that it's a good solution for not exposing too much unintelligible "system guts" to the player, since *all* of the game state is stored/represented by visible emoji! In the end, I was able to disguise most of the mechanical state as UI - unlike in most games where the health bar on the HUD is a visual depiction of the internal number that tracks the player's HP, in this game the health bar literally IS the player's HP! Kind of a wild concept, if you're used to the model/view/controller paradigm of game architecture; here the model and view are one and the same, and the controller mostly consists of things taped onto the modelview elements.
posted by NMcCoy at 3:47 AM on October 9, 2019


Took me a while for the concept to click but what a clever little game.
posted by AndrewStephens at 5:48 AM on October 9, 2019


« Older Peer Learning is......   |   All the Buddha Boxes: 70 Songs... Newer »


You are not currently logged in. Log in or create a new account to post comments.