So Isaac was frozen. What happened after Isaac? Shoshin happened!
Overview of what happened
Shoshin, a onchain AI fighting game concept, was rapidly prototyped, where a smart contract computes frame-by-frame the interaction between two characters, each controlled by an agent program, on a 2D plane; the resulting frames are then played-back visually in a pygame-based client.
We identified Shoshin was testing two hypotheses at the same time: (1) state machine is a relatable concept to non-engineer players; (2) state machine is expressive enough to represent agent behavior that leads to interesting fights.
Besides the two hypotheses above, Shoshin also has inherent complexity in requiring a frontend for scripting and simulation.
Opus Magnum (Zachtronics) inspired us to create a minimally-playable game loop in one day, which involved into the MovyMovy project (later renamed to MuMu). We have since shelved Shoshin temporarily to focus on MuMu.
Key findings
Design is subtraction.
Complexity is disastrous if: (1) a project originates from complexity; or (2) a project relies on complexity to get to minimal playable state / iteration #0.
Complexity at the birth of a project lengthens the time to iteration #0 with real players, yet it is precisely at iteration #0 with real players that the project touches ground-zero reality and could meaningfully progress.
If complexity is what it takes to reach iteration #0, further iterations will be difficult due to already-complex codebase/system.
Shoshin
In our internal dialogue about interoperability onchain back in May 2022, we became intensely interested in player-created behaviors. An easier way to understand this is player-created bots. If a game is played by bots only, but all bots are created by players, would this game be a native demonstration of blockchain programs?
Yes! Consider the following pattern:
Player designs an agent. The agent perceives from the environment, makes decisions and takes actions.
Player submits agent to the blockchain.
Agents get matched onchain to interact with one another.
We quickly realized this pattern is agnostic to TPS of the blockchain environment where the game runs, while this pattern focuses on the blockchain being the canonical place where records are made and settled - where agents make their fames and their creators be remembered. This pattern is analogous to the process of patent application - to submit a piece of new knowledge to be reviewed by some authority. Since a patent may have went through years of research and experiments, people do not expect patent review results to come back in merely days. Instead patent review takes months at least. Similarly, as a player spends a few days designing and testing her agent locally, after submission onchain she can afford to wait for up to a day to see how her agent performs in relation to other submitted agents.
Furthermore, on the topic of interoperability, we intuited that as the richness of agent behavior grows, there should be standards that form around the interfaces between agents and the environments they inhabit. These standards would allow agents created originally for different environments to traverse to other environments and retain their behavior; these standards would also allow permissionless and flexible creation of new environments for existing agents.
Given gg’s countless enjoyable hours spent in Naraka: Bladepoint (2021), we came up with the idea of player-created agents piloting characters that interact in a 2D fighting game setup, and we named the idea Shoshin - because players are creating the minds of the fighters. We prototyped Shoshin in 1 week, where we implemented a Cairo program that simulated all frames of a fight between agents that were represented by state machines, and used pygame to cheaply visualize the fight (with the sprites of Kyo from King of Fighters!). Overlap detection between hitboxes were implemented. Basic one-dimensional linear physics (acceleration, deceleration, max velocity etc) were also implemented. Cairo code base is open sourced here.
^Kyo-right punching Kyo-left. Hitbox dimensions and locations for all frames were emitted from Cairo via event and visualized in pygame. For details, check out the definition of the Hitboxes struct in Cairo here.
We then decided to make custom art because reusing King of Fighter licensed art only suited prototypes. We created the animation for each performable move for two characters we designed: Jessica, the agile katana-wielding girl, and Antoc, the tank wielding a great sword. We posted a demo where Jessica was controlled by a simplistic state machine that executed a demo action sequence.
^ Jessica executed the following actions in order: dash-forward, side-cut, dash-backward, side-cut, dash-forward, upswing, slash. The code that encodes this behavior is located here, which uses the input buffer technique (input buffer is a common control mechanics in the fighting game genre).
^Antoc’s horizontal swing, at the active frame (where damage box is active).
While developing our visual assets for Jessica and Antoc, we put more thoughts into the core gameplay activity: players editing their agent to “inject” behavior. Herein we discovered that Shoshin, when viewed as an scientific experiment, was testing the two following hypotheses simultaneously:
Accessibility: state machine is a mental model that is accessible to non-engineering-major players.
Expressivity: state machine as a data structure is efficient and expressive to encode sufficiently rich agent behavior that leads to meaningful fights - otherwise we risk trending toward Totally Accurate Battle Simulator-ish gameplay, which may be against our desire for aesthetics and complexity.
To test these hypotheses in-house, our close collaborator Greg took up the challenge to prototype a minimal defensive agent in Shoshin’s state machine spec (without using input buffer though):
^ a minimal defensive agent behavior drawn in schematic via Stately.
Yet besides these two hypotheses, there was additional source of complexity - how state machine is represented. If represented as full Cairo program, we either:
ask player to write Cairo (which we do not want); or
we ask player to write in some high-level scripting language / domain-specific language (which involves us designing that scripting language; this is still coding which seem utterly inaccessible to a lot of players who simply do not think in terms of abstract symbols); or
we build a visual no-code editor (e.g. Unreal’s Blueprint system) for players to build state machines by dragging and dropping visual elements (which involves a lot of UI interface work which we didn’t have confidence in building)
For option 2 and 3, we also needed to build programs that transform these high-level representations (scripts for option 2, diagrams for option 3) into Cairo - yet another piece of the system before it could work. Clearly, this was another complex and coupled system! Heeding the lessons learned from Isaac, we wanted to be extra vigilant of complexity explosion which kills iteration speed.
Design is subtraction
With Isaac and Shoshin, we viscerally woke up to the wisdom of design by subtraction.
Design is subtraction.
Complexity is disastrous if:
a project originates from complexity; or
a project relies on complexity to get to minimal playable state / iteration #0.
Complexity at the birth of a project lengthens the time to iteration #0 with real players, yet it is precisely at iteration #0 with real players that the project touches ground-zero reality and could meaningfully progress. Furthermore, if complexity is what it takes to reach iteration #0, further iterations will be difficult due to already-complex codebase/system.
In this lens, Isaac was complex, because it involved
a three-body simulation and collision detection onchain
a ticking system that ticks the universe forward at fixed block numbers
a building system that tracks entity connection, contiguity, resource and energy balance
an inventory system for players
coordination requirement
3 separate frontend views - Station (lobby queueing), Universe, and Planet.
etc
Even though the original prototype took only 7 days, Shoshin was still too complex before reaching iteration #0 because it involved:
a no-code frontend interface for players to visually program state machines. Note that we could compromise this by taking 0xMonaco’s approach - let players submit raw Cairo contracts directly; yet we did not want to compromise on that front just yet.
implementing the fight simulation in Typescript to allow frontend simulating the fight (so that players can iterate on their design in browser without touching the blockchain)
(Note: complexity is relative to team capability. Topology had ≤3 engineers working on any of these projects and not all of the 3 worked full time)
We became determined to find some absolute minimum design gesture that serves as the core mechanics of our next experiment. Something that is minimal but engaging in itself. Quoting from How to Prototype a Game:
Start with the core mechanic. Whether spring systems, swarm behavior, gravity, etc, it never took more than a few hours to get the basic theme up and running. This “toy” should be the core mechanic of the game minus any goals or decisions. There is no win or lose state, just a fun thing to play with.
Sparked by the brilliant works of Zachtronics - TIS-100, Opus Magnum, and Shenzhen I/O - we came up with a minimal design gesture that was engagingly fun from the get-go and was susceptible to lightning fast iteration. It was called MovyMovy and started on Oct. 11. Screenshot of MovyMovy on day 1: