Site Logo

Sparen's Danmakufu ph3 Tutorials Lesson 3 - Danmakufu Framework

The video for this lesson is Talos Mistake's entry for the RaNGE 10 contest. It won first place and was made quite a long time ago, but it remains as one of the most beautiful (in my opinion) scripts currently out there for ph3.

Part 1: What are the Different Script Types in Danmakufu?

In the last lesson, we learned that the Danmakufu menu contains options for things such as 'Single' and 'Plural'. Today we will learn what these things actually are and how scripters use them. In this lesson, we will also explore the fundamental parts of any Danmakufu script in ph3, and will begin our study of the Single, the building block of any boss battle.

First, let's go over the single, which tends to contain one attack, although it can be altered to include more or less than one depending on the goals of the scripter. Generally speaking, it will be one chunk of the boss's lifebar, and will contain either a nonspell or a spell.

Singles are surprisingly versatile. Since ph3 allows you to control significant parts of the system, you can have a nonspell turn into a spell halfway, use multiple bosses, and other things, depending on what you need.

Now let's go over the plural. A 'plural' script's primary function is to hold references to single scripts in order to chain attacks together into a boss battle. In 0.12m, this was basically the only way to make a boss (the exception here is Miransu Uwabami/Victini, who used a custom system that bypassed plural scripts altogether). Although ph3 allows you to put what would normally be placed in a plural script in a stage instead, I still highly recommend using plural scripts for boss battles, as it allows for easy and quick access to single scripts. Also, it is recommended that you master plural scripts before you move on to stages - beginning scripters will have limited use for stage scripts, which we will discuss next.

Stage scripts are the building blocks of full games and are also used in releasing standalone boss battles with built-in difficulty selection and other options. Stages can load plural scripts and come with a variety of customization options. Once you have mastered the usage of plurals, you will most likely move on directly to stages. However, that's for much later, so don't focus on this now.

Packages are new in ph3. In 0.12m, there was no easy way to allow access to replays and to create menus. However, ph3 added package functionality, which sort of acts as a main menu for your game. They are 100% customizable, although they have limitations in terms of which functions are allowed. Packages are used for complete games as well as projects where a main menu is wanted.

Although the above are the primary types of scripts, there are also a few key file types to note: Background and System files. We will discuss these in later detail in the future, but let's just say that you may want to use the defaults until you are comfortable with tasking and basic image and text manipulation in Danmakufu.

Quiz: Types of Scripts

Suika would like to make a nonspell for a boss battle in Danmakufu. Which of the following script types should she use?

A. Stage
B. Single
C. Plural

Part 2: What are the Components of a Danmakufu Script?

Click this link to open massive wall of code in a seperate window

If you have no experience with Computer Science, you are probably completely overwhelmed by this wall of code. This particular single is the translation (from Japanese) of SampleA01, located in the 'sample' directory inside your ph3 script folder. This is code written to be used as a template for scripters, and as such, it is what I will use as an example. For future reference, do make use of the sample scripts (and the ExRumia boss and player), as they are a useful resource.

So now we will look at the text and will take it apart piece by piece.

Part 3: What are the Components of the Danmakufu Header?

First, there are things at the top prefixed by the hashtag #. These (not the include - just the top portion) make up the Danmakufu Header. The first line is #TouhouDanmakufu[Single]. This designates the script as a Touhou Danmakufu script - without this line, Danmakufu will not read the file as a danmakufu executable and it will therefore not show up in any of the searches (e.g. All, Directory, etc.). In place of 'Single', you can also use 'Plural', 'Stage', and 'Package', the types of scripts elaborated upon in Part 1.

Next there is #ScriptVersion[3]. As stated by the comment next to it, located after the //, it is required for all ph3 scripts. #ScriptVersion[2] refers to Danmakufu 0.12m and #ScriptVersion[1] refers to something made back when Touhou 10 didn't exist. Let's just say that you just need to have #ScriptVersion[3] for ph3 to run the script correctly.

After the script version are two fields labeled #Title and #Text, with a string inside containing the whatever information is used to describe the fields. What is placed in #Title will appear as the label for the script when you traverse Danmakufu's script lists, and #Text describes the text in the bottom left quarter of the screen. I highly suggest never leaving #Title blank, as it can confuse people browsing through a folder if you suddenly have a script with no title - if you do not want Danmakufu to list the script when it spits out the list of all executable scripts, it's better to comment out the #TouhouDanmakufu[ScriptType] line instead. How to manipulate strings in ph3 as well as how to comment will be discussed in a later tutorial.

As a quick example, see the following. Note that [r] is used for line breaks.

#Title["Descent of the Mochi Hammer - Stage 6"]
#Text["Descent of the Mochi Hammer[r]Stage 6[r]By Sparen"]

Additionally, there are some fields that are not shown here, #Image, #BGM, #Player, #Background, and #System. These are the optional portions of the header.

First I will discuss #Image and #BGM. #Image controls whether or not an image will be displayed in the bottom right quarter of the screen when you are hovering over a particular script in Danmakufu's menus. If you want to include an image, you will place the path to the image inside the brackets, but most people don't bother to do this. It's perfectly fine to just not have it. You can include a path to a music file in #BGM to play a music track. This is quite useful if you don't want to load and play the bgm file manually, but there are varied usages for both.

#Player can be used to limit the players that can be used. This is mainly used to specify a specific player (usually included with the script). If you do not want to specify a player to be used, omit this field entirely. To specify multiple players, you should have a comma between the file paths. For example:

#Player["./player/A2MarisaSparen/A2Marisa.txt", "./player/Ultima's DDC Reimu B player/ReimuH.dnh"]

#Background and #System are used to specify custom background and system files to use in place of the defaults. We will get into this much later on.

CHECKPOINT: Which header fields are required? Why?

Part 4: What are the Main Routines Used in a Single?

Now we will shift our focus elsewhere. We will ignore the plethora of comments and let statements and will instead focus on the items prefixed with @. These are the routines of a Single script. As listed on the page, there are @Event, @Initialize, and @MainLoop, as well as @Loading and @Finalize, which are meant to be used in conjunction with one another when loading resources. Beginners should simply ignore @Finalize and @Loading until they are creating larger projects. Note that the L in @MainLoop is capitalized. Danmakufu is case sensitive. Do not use @Mainloop or your script will not work because MainLoop and Mainloop are two completely different things.

First I will discuss @Initialize. In @Initialize, which only runs once at the start of the script, the commands in between the braces {} are executed in order. Here you will register the enemies, prepare resources, and usually move the boss to its desired starting location. I will not get into more detail about these now, but you will gradually learn what to put here as you gain your own coding style. I will discuss this when we assemble our first Single script.

Next is @MainLoop. By default, this routine runs once per frame. There are 60 frames in a second, hopefully, as displayed in the FPS meter. Since @MainLoop runs every frame, it is commonly used for things that need to run each frame, such as setting the boss's hitbox. You can control a number of things here, although most scripters tend to use tasks either in conjunction with @MainLoop or completely independently of @MainLoop. We will get into this later as well.

Next is @Event, which was introduced in ph3. Here, various 'events' are controlled, and you will set things such as spell bonus, boss life, and other things here. We will briefly talk about @Event when making our first single, although since it can get complicated, most of the details will be held off for higher level tutorials.

Finally, @Finalize, which was present in 0.12m, and @Loading, which was introduced in ph3. @Loading runs once before @Initialize and should only be used for loading resources. In the far far future, there may be a significantly more thorough explanation of what @Loading does, but for now, just be aware that it exists. @Finalize runs once at the end of a script and is used for deleting loaded resources. Both of these are completely optional and can be omitted from a script.

In the next lesson, you will learn about comments, variables, and a number of other components of programming and scripting languages, as well as Danmakufu syntax. However, for now... here's a quiz.

Quiz: Danmakufu Framework

Reimu is very angry. She cocks her head one way, and then the other. However, she can't figure out why her script isn't showing up in the list of scripts in Danmakufu ph3's Directory lists. She has reloaded, made sure that the file is in the script directory, and has even considered calling Nitori over. Her Danmakufu header is below, and every line prefixed with a # in the entire script is included in this header.

#Title["Red and White"]
#Text["Who are the thieves stealing from my donation box?"] 

Why is her script not showing up?

A. She is using #ScriptVersion[3] instead of #ScriptVersion[2]
B. She forgot to put #TouhouDanmakufu[Single]
C. She did not put a script version.
D. It's Yukari's fault

Sources and External Resources

[ 弾幕風 PH3 Tutorial ] Introduction to Danmakufu (Helepolis)
-->Not particularly relevant yet, but will be in the next few lessons