#import "gdd_template.typ": * #import "@preview/gentle-clues:0.7.1": question, info, quote as quotation #import "@preview/cetz:0.2.2" #show: gdd.with( title: [IO], authors: ( ( name: "Jengamon", url: "https://nest.pijul.com/Jengamon/bevy_games/" ), ) ) = Introduction == Game Summary #figure( cetz.canvas(length: 3cm, { import cetz.draw: * set-style( mark: (fill: black, scale: 2), stroke: (thickness: 0.4pt, cap: "round"), angle: ( radius: 0.3, label-radius: .22, fill: green.lighten(80%), stroke: (paint: green.darken(50%)) ), content: (padding: 1pt) ) grid((-1.5, -1.5), (1.4, 1.4), step: 0.5, stroke: gray + 0.2pt) circle((0,0), radius: 1) line((-1.5, 0), (1.5, 0), mark: (end: "stealth")) content((), $ x $, anchor: "west") line((0, -1.5), (0, 1.5), mark: (end: "stealth")) content((), $ y $, anchor: "south") for (x, ct) in ((-1, $ -1 $), (-0.5, $ -1/2 $), (1, $ 1 $)) { line((x, 3pt), (x, -3pt)) content((), anchor: "north", ct) } for (y, ct) in ((-1, $ -1 $), (-0.5, $ -1/2 $), (0.5, $ 1/2 $), (1, $ 1 $)) { line((3pt, y), (-3pt, y)) content((), anchor: "east", ct) } // Draw the green angle cetz.angle.angle((0,0), (1,0), (1, calc.tan(30deg)), label: text(green, [#sym.alpha])) line((0,0), (1, calc.tan(30deg))) set-style(stroke: (thickness: 1.2pt)) line((30deg, 1), ((), "|-", (0,0)), stroke: (paint: red), name: "sin") content(("sin.start", 50%, "sin.end"), text(red)[$ sin alpha $]) line("sin.end", (0,0), stroke: (paint: blue), name: "cos") content(("cos.start", 50%, "cos.end"), text(blue)[$ cos alpha $], anchor: "north") line((1, 0), (1, calc.tan(30deg)), name: "tan", stroke: (paint: orange)) content("tan.end", $ text(#orange, tan alpha) = text(#red, sin alpha) / text(#blue, cos alpha) $, anchor: "west") }), caption: [the _*real*_ content] ) Io (stylized _IO_) is a platformer bullet-hell about escaping the depths of a decaying and rusting factory to the surface above. #question(title: [About the name _Io_])[ I was today years old when I looked up #link("https://en.wikipedia.org/wiki/Io_(moon)")[Io on Wikipedia] and it's an infernal hellscape. Do we play on this? #small[yes.] _I was always thinking of Europa!_ ] == Inspiration This goes out to young me thinking they want to make Cave Story again. Got me into gamedev, and eventually to work as a programmer, but making games has always been close to my heart. Beyond collecting the tools that I _think_ should be sufficient to complete a game, this is a reduced scope idea to get more of a feel of how to use the tools, while making a cool game! === #link("https:/develop.games")[Pirate Software] Motivation to move beyond tutorials and toys to invest the time to put together something of a "completed product". === Other Inspirations #lorem(60) == Player Experience There are 4 levels to platform across, all consisting of a subboss, and a main boss. For now, there is 1 side quest per level, providing an additional skill. The player learns to time their combos (Ideal timings and all), and learn how to transverse the platforms, understanding the patterns of each boss, in order to complete the levels and reach the surface. == Platform The game will be released for Desktop primarily, with no intentions of requiring a web build (if there is one, it will only be for a demo to download the desktop version). == Development Software We are using #link("https://bevyengine.org")[Bevy Engine] and #link("https://rust-lang.org")[Rust]. I've really wanted to take the time to learn how to use Bevy, and Rust is plain fun to me, so here we are. The high-risk part of this is that Bevy is not stable software, but the guarantees of Cargo should mitigate incompatibilities due to this, and the Bevy ecosystem has a really good precedent of marking explicitly the compatible versions of their packages with the core Bevy engine, which makes this doable. For code editing, I'm using a mix of #link("https://helix-editor.com")[Helix] and #link("https://zed.dev")[Zed]. Graphics are in #link("https://aseprite.org")[Aseprite]. Audio is coming from #link("https://github.com/tildearrow/furnace")[Furnace Tracker] for main themes, but #link("https://bitwig.com")[Bitwig Studio] for general sound design ideally, but we'll have to see. #link("https://github.com/SamiPerttu/fundsp")[FunDSP] is an interesting project. Our audio system itself is powered by #link("https://github.com/tesselode/kira")[Kira] instead of using the default `bevy_audio`. The other major experimental part of this game is that scripting will use #link("https://github.com/kyren/piccolo")[Piccolo], an implementation of Lua in Rust that tries some different things. If it doesn't work out, as we design Lua interfaces, we can substitute in #link("https://github.com/mlua-rs/mlua")[MLua] with minimal API breakage. == Genre We are a platformer bullet-hell, in that order. Bosses are where the bullet-hell aspect becomes incredibly apparent. We are a single player game. This is an involved game (but we *must* support full pausing because of that). == Target Audience Because our combat system is relatively involved, and bullet hell sections are involved, platformer proficiency is required/expected. = Concept == Gameplay Overview #lorem(600) == Themes #lorem(300) == Primary Mechanics #lorem(600) == Secondary Mechanics #lorem(600) = Art == Themes #lorem(300) == Design #lorem(300) = Audio == Music #lorem(300) == Sound Effects #lorem(300) = Game Experience == UI #lorem(300) == Controls #lorem(300) = Development Timeline #dev_timeline( ..dev_timeline_event(name: "Create GDD", completed: true, date: ymd(2024, 4, 21))[Start the GDD and the design process], ) = Terms #set terms(separator: [#sym.angle.r ]) / Ideal: A time period with every move where cancelling into the next move leaves the damage unchanged (instead of multiplying the damage by x0.7), but if the opponent hits you during this time, they deal x1.5 stagger damage. / Stagger: A stat that when filled, stuns the entity. / Overstagger: If an entity is dealt stagger damage while they have over the amount of max Stagger they have (tends to happen if they were uninterruptible), the difference between their Stagger and their max Stagger is dealt as unblocked damage them directly before stunning them. / Uninterruptible: All moves have 3 stages: #code_term("Windup"), #code_term("Execute"), and #code_term("Winddown"). Uninterruptible means that an entity cannot be struck out of their #code_term("Windup") nor #code_term("Execute") phases (however damage and stagger damage goes through as normal)