-
Notifications
You must be signed in to change notification settings - Fork 2
Improvements
BulletML is a powerfull language that allow us to write complex bullet pattern in only few lines.
But a lot of things can't be done or are not done the proper way.
This document presents a list of changes that will improve BulletML and the parser for me, even if most of these suggestions would break the retro compatibility with former BulletML scripts.
It's possible that one or more of these following things are actually feasible with BulletML, if it's the case, please tell me how.
- Draw specific patterns with bullets like an object or write text => It's not as easy as it sounds, but with
<changeDirection>
,<changeSpeed>
and<wait>
tags, we can draw almost everything. - Fire ellipsis or perform some 3D like effect
- Fire sequence bullets simultaneously (if we want to fire left and right spirals at the same time for instance) => It's possible using multiple
<action label="top#"></action>
tags, but it's limited to the pattern's beginning.
Make it FPS independent: BulletML assumes that the game runs at 60 FPS, it doesn't use time but frame as reference. It's a big mistake because it implies that the bullet patterns will not be executed at the same speed on every devices. A fork already did some changes to fix this depency to the framerate, but I would like to go further replacing all references of frame by time in the BulletML language. It means that <wait>
and <term>
tags will take time in milliseconds instead of frame.
A BulletML script doesn't have anything related to the graphic part of bullets.
RGBA -> Between 0 and 1. Take the values from <red>
, <green>
, <blue>
, <alpha>
and <opacity>
child nodes. If we don't use attributes for these values, it's because we want to be able to use math expression like that:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE bulletml SYSTEM "bulletml.dtd">
<bulletml>
<action label="top">
<fire>
<bullet>
<speed>1</speed>
<color>
<red>$rand</red>
<green>$rand</green>
<blue>$rand</blue>
<alpha>1.0</alpha>
<opacity>0.5</opacity>
</color>
</bullet>
</fire>
</action>
</bulletml>
This implies to give a list of specific assets to the instance of BulletML manager. Should we specify the sprite dependencies in the BulletML pattern file?
With a <color>
and a <term>
nodes. It will be possible to hide a bullet updating its alpha value.
Use sprite ID. We need to give a Dictionary<Id, Sprite> as a parameter of the MoverManager
?
No <term>
tag, the switch takes effect immediately.
<bullet>
<trail>10</trail> <!-- Size of the trail -->
</bullet>
Into <fire>
tag to play sound:
<fire>
<sound>10</sound> <!-- Sound index -->
<bullet />
</fire>
To teleport a bullet to another location.
In ms exactly like for a particle engine. => Or use the existing <vanish>
tag passing a additional attribute (none
, outofbound
, time
).
Or <collide>
, to change the bullet's behaviour when it touches the game area border.
<bullet>
<collide>
<action>
<changeDirection>
...
</changeDirection>
</action>
</collide>
</bullet>
To be able to spawn a bullet with an offset relative to its original spawn position.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE bulletml SYSTEM "bulletml.dtd">
<bulletml>
<action label="top">
<fire>
<bullet>
<speed>1</speed>
<offsetX type="absolute">100</offsetX> <!-- 100 pixels offset on the world X axis -->
<offsetY type="relative">-100</offsetY> <!-- -100 pixels offset on the local bullet Y axis -->
</bullet>
</fire>
</action>
</bulletml>
Or <start>
or <mainAction>
to remove the specific case of the <action label="top">
Instead of writing <times>9999</times>
, we should have a specific value (0 or -1) that means the loop is infinite:
<repeat>
<times>0</times>
<action>
<fire>
<bullet />
</fire>
</action>
</repeat>
It should be the same behaviour if we omit the <times>
tag. Make sure to properly raise an error when we parse an infinite loop without <wait>
tags!
<repeat>
<times>10</times>
<action>
<fire>
<bullet>
<direction>$index * (360 / $maxIndex)</direction>
</bullet>
</fire>
</action>
</repeat>
$width
and $height
.
Keeping the sequence
attribute, adding these variable will allow us to do more things.
$gameTime
and $patternTime
$playerDistance
, specific to each bullet.
BulletML is very clever and simple to use, especially because it's possible to make complex patterns without using custom variables or conditions. But this is also its main limitation, and some patterns are simply impossible to reproduce. Let's take the example of Touhou Satori's last spell cards: it's just a rotating pattern with a variable angle updated according to time.
Some tags change a bullet state over time (<changeDirection>
, <changeSpeed>
, and <accel>
tags) with a linear interpolation. It will be great to be able to specify what kind of interpolation we want through a new attribute:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE bulletml SYSTEM "bulletml.dtd">
<bulletml>
<action label="top">
<fire>
<bullet>
<speed>1</speed>
<action>
<changeSpeed tweening="cubic">
<speed>10</speed>
<term>100</term>
</changeSpeed>
</action>
</bullet>
</fire>
</action>
</bulletml>
It makes a lot more sense if the default direction is absolute
instead of aim
.
Generally, a pattern is triggered by a moving entity, and it seems logical than if the entity is moving, the pattern's spawn position moves too. Actually, it's not the case, the bullets spawn position is relative to a root bullet fired only once, so even if the moving entity changes its position, the root bullet doesn't move.
- Useless attribute
horizontal
orvertical
in thebulletml
tag. - No root bullet anymore, the only ones bullets that we shoud see is the ones fired by a
<fire>
tag. - Replace
<changeDirection>
,<changeSpeed>
and<accel>
tags by a global modifier like an<update>
or a<change>
tags that can change direction, speed and acceleration at the same time. - Remove
<bulletRef>
,<fireRef>
and<actionRef>
tags and use already existing<bullet>
,<fire>
,<action>
tags with aref
attribute => we can use a kind of inheritance still keeping the useful<param>
tag. -
Remove=> Wrong idea: we can't use math expression into node's attributes.<times>
tag and make it an attribute of the<repeat>
tag instead. - Replace all
<term>
tags by<time>
(in ms)
Another person also thought of some improvements of the BulletML language and called it BulletMLX.