[HN Gopher] Firedancer: Language for 2D shmups bullet-hell patterns
       ___________________________________________________________________
        
       Firedancer: Language for 2D shmups bullet-hell patterns
        
       Author : bitbasher
       Score  : 180 points
       Date   : 2024-08-12 04:34 UTC (3 days ago)
        
 (HTM) web link (firedancer-lang.com)
 (TXT) w3m dump (firedancer-lang.com)
        
       | dang wrote:
       | Looks like these are related:
       | 
       |  _BulletML is a markup language that describes the barrage of
       | bullets in shooting games._ -
       | https://news.ycombinator.com/item?id=410898 - Dec 2008 (2
       | comments)
       | 
       | https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...
        
         | freeone3000 wrote:
         | Sixteen years ago!
         | 
         | I saw "applet" and thought it was retro, then someone tried it
         | in firefox 3 and I had to check the year.
        
         | noufalibrahim wrote:
         | Yes. I was exposed to this when I came across kenta cho's
         | games. I even tried to use it a little iirc for a shooter i was
         | playing with but couldn't get very far and abandoned it.
        
         | bitbasher wrote:
         | BulletML was developed by ABA Games (aka kenta cho, creator of
         | the classic rrootage, which is now open source).
         | 
         | It was rrootage that sent me down a rabbit hole and eventually
         | stumbled onto fal-works and firedancer after someone suggested
         | their works had the same aesthetic appeal.
         | 
         | The libbulletml c++ library is still somewhat used in some
         | niche vertical shmup games (mostly Japanese indie games). You
         | can read a little about bulletml and the history of it all in
         | the libbulletml readme file.
         | 
         | [0] https://en.wikipedia.org/wiki/ABA_Games
         | 
         | [1] https://github.com/abagames/rrootage
         | 
         | [2] https://shinh.skr.jp/libbulletml/README.en.txt
         | 
         | [3] https://www.fal-works.com/solid-aether
        
           | valryon wrote:
           | BulletML is also used in some more recent Unity3D games like
           | Steredenn
        
             | yoz wrote:
             | ... and the wonderful _Enter the Gungeon_ (praise Kaliber)
        
       | chii wrote:
       | This is pretty cool!
       | 
       | It's even haxe based!
        
       | miffe wrote:
       | Seems to be vsync-based. Would make the laundry pattern very hard
       | at 360Hz :)
        
         | eru wrote:
         | What's the laundry pattern?
        
           | mock-possum wrote:
           | Choose it from the 'example' select box and see for yourself
           | ;)
        
             | eru wrote:
             | OK, thanks! I found it.
             | 
             | But why would vsync make that hard? You mean if it's 1:1 on
             | the vsync?
        
               | Karliss wrote:
               | I guess the idea is was that Firedancer is designed with
               | fixed update rate in mind. And the demo makes an
               | assumption that it will run at 60 FPS = 60 updates per
               | second, probably becoming very fast and hard on 360 Hz
               | screens. But that's just nitpicking on details in library
               | demo. It would be bad to have such mistake in a real game
               | or game engine demo, but it's not that surprising for
               | example code to skip details for the sake of simplicity.
               | The main purpose of example is demonstrating the library
               | as cleanly as possible without distracting reader by
               | containing more boiler plate code for third party game
               | engine than the thing it's attempting to demonstrate. I
               | don't see a reason why you couldn't update FireDancer VM
               | at whatever fixed rate you want (faster or slower than
               | typical FPS) just like many games and game engines with
               | fixed tick rate for physics or game logic handle it.
        
               | unconed wrote:
               | If the shots weren't timed to a regular fixed clock, then
               | there would be visual jitter in the pattern. Even if you
               | correctly spawn shots in between two ticks, each bullet
               | would only first appear some random distance along its
               | trajectory.
               | 
               | If an enemy spawns e.g. a circle of bullets, you would
               | see it rapidly expanding/contracting.
               | 
               | I suspect a variable frame rate bullet hell game would be
               | harder to play, but I'm not a fan of the genre.
        
           | tetris11 wrote:
           | Check out the "static geometric" pattern too while you're at
           | it, there's a zooming out optical illusion occurring there
        
         | Lockal wrote:
         | Laundry looks easy! Just move slightly to the left from bottom
         | center to the safe zone. And speaking of safe zones, so many
         | frameworks miss the opportunity to visualize them, calling for
         | Ice Sign "Icicle Fail" in almost every geometric shmup.
        
       | redrobein wrote:
       | Can you add a little player box and make this playable with
       | touhou style controls. For testing purposes ofcourse.
       | 
       | Ah. I thought the script was being compiled inbrowser. These are
       | prerendered.
        
         | Karliss wrote:
         | Looking at the demo source code it seems like it is running
         | everything in browser and is not prerendered. It just lacks a
         | parser. So the AST nodes in all examples are created through
         | function calls https://github.com/fal-
         | works/firedancer/blob/4a15e80fe55893b... .
        
         | ginko wrote:
         | Yeah, kind of disappointing. I was hoping I could play around
         | with this a bit in the browser.
        
       | qwery wrote:
       | BulletML[0] (circa _Java applet, AD_ ) is a markup language to
       | describe shmup bullet behaviours. The Firedancer README says the
       | project is "Inspired by BulletML". Cool to see it living on, in a
       | way.
       | 
       | But where is the toothpaste laser? _What even is a toothpaste
       | laser?_ I hear you cry, well...
       | 
       | Today in _Search Engines: Software for No-one_ , I try (somewhat
       | naively) to search for "toothpaste laser" in hope of finding an
       | accurate analysis/explanation/implementation of the famous
       | weapon/s from the Raiden series.
       | 
       | It won't surprise you to learn that this got me a grid of photos
       | of toothpaste tubes and mechanically-induced fluorescent grins.
       | It might surprise you to learn that prepending 'raiden' to my
       | query barely helped. If only there was a search engine that
       | _allowed the user to decide what to search for_.
       | 
       | Long story short, Raiden (series) is about as popular as the
       | intersection of Raiden (Kharacter) and referring to electrical
       | arcs as "lasers"[1]. Both of these topics are totally eclipsed by
       | the Bend-Tech Dragon A400: The Essential CNC Tube Production
       | Machine[2].
       | 
       | [0] http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html
       | 
       | [1] not that any of the toothpaste lasers are lasers
       | 
       | [2] it is essential, after all
       | (https://www.youtube.com/watch?v=xMb9XZjK6m0)
        
         | anonymoushn wrote:
         | Maybe you mean this sort of thing (first image result for
         | "raiden purple laser")
         | https://gamedev.stackexchange.com/questions/29424/what-are-t...
        
           | qwery wrote:
           | That's referring to the same "toothpaste laser", yes. The
           | discussion never arrived at a satisfactory algorithm -- I
           | tend to agree with the gist of the incremental "steering"
           | ideas, though.
        
           | renewiltord wrote:
           | Absolutely bonkers
           | https://youtu.be/0SEcyot2qgA?si=m_J17m2q6PMzuDhv&t=107
        
             | anonymoushn wrote:
             | Per the description at
             | https://www.youtube.com/watch?v=XVoZ-1le8s0 the weapon is
             | pretty weak. It has to be to compensate for not needing to
             | aim it at all, but it seems like even then it's not worth
             | it. It's pretty iconic though. I'd like to see it in more
             | games.
        
               | yoz wrote:
               | It's in (the BulletML-using) _Enter the Gungeon_ as the
               | "Raiden Coil"
               | 
               | Video: https://www.youtube.com/watch?v=Vkr0mYdRZdU
               | 
               | More info:
               | https://enterthegungeon.fandom.com/wiki/Raiden_Coil
        
       | GuB-42 wrote:
       | I see BulletML being mentioned but there is a third one:
       | CannonML.
       | 
       | https://web.archive.org/web/20120626041044/http://www.libspa...
       | 
       | Haxe port: https://github.com/gunnbr/CML
       | 
       | As you may have guessed by the archive.org link, it doesn't have
       | much support. Compared to BulletML and Firedancer, it has a very
       | terse and rich syntax that kind of makes me think of Perl.
        
         | qwery wrote:
         | I wasn't sure exactly what you meant by "terse and rich syntax"
         | but I wasn't expecting the example on the CML github which is
         | referred to as _quite cryptic_ :
         | 
         | > bs,4,,10bm5,360f10{i30vw90br5,360,2,2f4{i30v~ko}w10ay0.05}
         | 
         | That is certainly terse!
         | 
         | [aside: I'm not usually one to _pedant over_ what qualifies as
         | a  "markup language", but I have to say this is not it. I'm
         | happy to report that the author didn't think so either, because
         | the 'ML' stands for "macro language".]
        
           | philipov wrote:
           | Yeah, that's not _Perl_ ; that's _Q_!
        
       | CyberDildonics wrote:
       | This is unfortunately a classic example of mixing data with
       | execution. Data is easy to understand and manipulate. Execution
       | is much harder because you don't know what it produces without
       | executing it.
       | 
       | Inventing a language is the third step and even worse, because
       | you not only have execution instead of data, but you wipe out the
       | entire ecosystem of tools, libraries, fragments and knowledge and
       | start all over again.
        
         | anonymoushn wrote:
         | Defining the behavior of enemies and bullets in a shmup is
         | programming. I'm not sure how you want it to be done without
         | the programming part. Could you maybe show us?
        
           | CyberDildonics wrote:
           | _Defining the behavior of enemies and bullets in a shmup is
           | programming._
           | 
           | Says who? And for what definition of programming?
           | 
           |  _I 'm not sure how you want it to be done without the
           | programming part._
           | 
           | Maybe you should point out the parts that can't be static
           | data.
           | 
           | Even branching, triggers or graphs could be straight data.
           | 
           | Which parts needs loops, state and computation?
        
       | mariocesar wrote:
       | Is there a book that teaches these patterns? looks so useful to
       | known when building games
        
         | netdoll wrote:
         | The classic book references for programming shmup bullet
         | patterns (in Japanese) are
         | shiyuteingugemuarugorizumumaniatsukusu and shiyuteingugemu
         | puroguramingu, but in general, a lot of this stuff is folk
         | knowledge and isn't communicated well outside of trial and
         | error until you get something passable. I would suggest looking
         | up web tutorials and game source code and learning from that
         | (also will mention the Development sub forum on
         | shmups.system11.org being quite useful).
        
           | mariocesar wrote:
           | Thank you !
        
       | slmjkdbtl wrote:
       | This is cool but I never understand most DSLs, looks like most of
       | them can just be defined as some functions in your host language.
       | The example on the main page just looks like JavaScript and you
       | define the parallel(), radial() functions yourself to return some
       | data, and a run() function to deal with these data / run the
       | game. Writing a compiler and VM for this is a huge overkill imo,
       | if it aims to be productive and not just a programming practice.
       | Am I missing something?
        
         | anonymoushn wrote:
         | A run() function to deal with the data is an interpreter (the
         | data has stuff like calls to the wait function and subroutines
         | in it) or at least a command-replayer, if the control flow all
         | runs before any gameplay happens. The behavior might also be
         | dynamic such that the command-replayer approach doesn't work.
         | 
         | One reason BulletML is useful compared to a general-purpose
         | language is that you could arbitrarily recombine BulletML ASTs
         | to produce valid bullet patterns, which Kenta Cho did for
         | rRootage[0]. I think another reason that people implement VMs
         | for these languages is that the host language lacks coroutines,
         | so it cannot express the wait() function, and they don't want
         | to turn their bullet pattern code inside-out. Even if the host
         | language has coroutines, they may not be serializable, so
         | saving your game in the middle of a level may not be possible
         | if you build on top of coroutines, whereas it is definitely
         | possible if you control the interpreter state of your DSL.
         | 
         | [0]: https://www.asahi-net.or.jp/~cs8k-cyu/windows/rr_e.html
        
         | jayd16 wrote:
         | I find that a lot of DSLs are essentially "I need these N
         | languages features in a serializable and dynamically runnable
         | language." If you're already in a scripting language its not
         | all that interesting but if you're in a compiled language, a
         | small embedded DSL can scratch an itch.
         | 
         | Even in JavaScript, you might not want the full power of eval()
         | exposed and instead you want something with less power that can
         | be parsed and sanitized.
        
         | fitsumbelay wrote:
         | > Writing a compiler and VM for this is a huge overkill imo
         | 
         | Personally, that's what attracts the artist side of me to this,
         | like it's the ultimate creative product. There seems to be a
         | lot of blogging and tweeting recently around the subject has
         | also created a bit of an itch.
        
           | slmjkdbtl wrote:
           | I understand where you're coming from. I also value a lot on
           | the artistic side of a project, but if you compare to a
           | project like 100r's uxn, a lot of custom language / vm
           | projects fall a bit short on both the creative and utility
           | sides. But still, I'm all for creating things just for
           | oneself or just for the pleasure of creating it.
        
             | fitsumbelay wrote:
             | fair I'm curious how you feel uxn fails as a utility (eg.
             | missed stated goals? or unstable and therefore not
             | practical? ) and as a creative product tho it'll be hard to
             | take comments on the latter as objective.
        
       | philipov wrote:
       | The way the scripts are presented in a text box makes it feel
       | like I should be able to edit the text box contents and have the
       | change represented in the image. It's a bit disappointing that I
       | can't play around with it like that.
        
       | mrandish wrote:
       | I find myself strangely drawn to Japanese bullet-hell shmups
       | despite sucking at playing them. There's something about peak 2D
       | pixel art sprites over parallax scrolling fantasy environments
       | while dodging through insane geometric bullet patterns and
       | spectacular animated explosions that's beautiful and hypnotically
       | compelling.
       | 
       | I just wish I wasn't so hopeless at them, only managing to
       | survive seconds at a time by constant credit feeding. While I
       | realize the entire genre is notorious for being brutally
       | difficult and that's in fact the appeal to many serious players,
       | I dream of shmups where:
       | 
       | * Difficulty scaled dynamically up a smooth gradient based on
       | real-time player performance
       | 
       | * Success didn't require deep level and pattern memorization. My
       | cognitive style is anti N-back and this requisite shmup ability
       | remains forever beyond my reach. I need the shmup equivalent of
       | Fischer Random Chess (aka Chess960) where the necessity of book
       | memorization is removed and the focus is mostly on reactively
       | dodging in the moment.
       | 
       | * The engine supports interactive practice modes enabling weaker
       | players to gradually build skills such as: rewind, ghost follow
       | and partial dynamic slowdown (eg only bullets get slower, only
       | when N of bullets > Threshold, growing gradually slower as N
       | increases, returning to normal below N).
       | 
       | On the last point, some modern shmups do at least have "practice
       | modes" but they seem like developer afterthoughts, typically very
       | basic bolt-ons instead of being integrated, dynamic and granular.
       | The result often leaves me feeling more frustrated than trained.
       | While it is possible to apply hacks to emulated shmups which can
       | help a bit, these are usually limited to brute force such as
       | pause, global frame rate limiting and infinite lives or
       | invincibility. While MAME and Retroarch do have rewind features,
       | I believe they are hacky since I've never been able to get them
       | to work reliably with shmups.
       | 
       | My deep attraction to the genre seems doomed to remain unrequited
       | despite buying and playing so many, watching various training
       | videos and following many guides. I feel like I can't reach the
       | level needed to trigger the fun-obsession loop of a typical
       | bullet-hell shmup because it currently requires a minimum level
       | of a few neuro-competencies I don't possess. Even top players and
       | fans admit (and occasionally revel in) the inaccessibility of the
       | genre, highlighting the need to memorize deep pattern sequences,
       | commit dozens of hours to rote practice and how it helps to be
       | "at least a little on-the-spectrum."
       | 
       | This makes me sad because top players, fans and developers are
       | also worried about the long-term decline of the genre from cool
       | niche in the 90s to seriously at-risk in recent years. I suspect
       | there may be others who are, like me, strongly attracted to
       | shmups but too-often barred by a metaphorical "Must Be This
       | 'Neuro-Level' to Ride" sign. Yet other once niche gaming genres
       | have successfully broadened their appeal by deeply integrating
       | 'accessibility' features like racing games have done with: ghost
       | cars, rewind and suggested driving line/speed indicators, and
       | fighting games with granular, smooth-scaling training modes with
       | extensive on-screen instruction.
        
         | anonymoushn wrote:
         | I enjoyed the western shmup Jamestown which is tuned to be easy
         | as long as you are playing the couch co-op mode.
        
         | bitbasher wrote:
         | I recommend taking a look at "The Electric Underground"'s
         | videos on how to get better at shmups. He has a lot of useful
         | advice (where you should be looking while playing, conventions,
         | how to see danger, etc).
         | 
         | [0]:
         | https://www.youtube.com/watch?v=5LQ3a5D2OKY&list=PLMDuVHl1iO...
        
           | mrandish wrote:
           | Thanks, I have watched several of his videos previously and
           | they are indeed full of good tips but somehow I'm still not
           | able to get to the point where the shmup loop kicks in. For
           | me, I think it's not mainly an issue of knowledge or
           | technique, hence my post with ideas on how future shmups
           | might be made more accessible to those like myself.
        
       | davidpfarrell wrote:
       | Awesome - I have designed similar things in my head dozens of
       | times over the years. Often I end up drifting into thoughts away
       | from these deterministic patterns and into a more adaptive
       | approach based on how the user is performing - At least at the
       | 'closer to the boss' parts of the levels ...
       | 
       | Just the same thanks for sharing and I'm enjoying playing around
       | with this !
        
       | imiric wrote:
       | While these patterns are pretty to look at, I don't think bullet-
       | hell shmups are fun to play. The challenge becomes to very
       | carefully dodge bullets that appear in the same pattern over and
       | over again, instead of, you know, actually shooting at the enemy.
       | Yes, dodging is part of shmup gameplay, but I find it much more
       | enjoyable when the bullets don't have a recognizable pattern, and
       | when the goal is not to overwhelm you with the amount of them on
       | the screen.
       | 
       | I love the shmup genre, but would rather play traditional ones
       | like Raiden, DemonStar, R-Type, Gradius, Blazing Star, etc., and
       | modern entries like Sky Force, than Ikaruga and the like. But,
       | hey, to each their own. :)
        
       ___________________________________________________________________
       (page generated 2024-08-15 23:01 UTC)