Page Index


The LUA scripts can be used for both player scripts and stage scripts. Player scripts store their functions in a single table (referenced by the code field in the player's .ini file). Stage scripts work by calling a global function main. Execution of the main function is started at the beginning of the stage, but thanks to the yield(frames) function it's possible to suspend execution for a number of frames (at 60 frames/s). The yield function is specified in TouhouDS/script/stdlib.lua.


LUA's built-in math library is not available, replacement math methods are available (called like this: Math.rand(128, 256)).

rand()Returns a random number (unbounded).
rand(max)Returns a random number in the range [0, max).
rand(min, max)Returns a random number in the range [min, max).
abs(v)Returns the absolute value.
min(a, b)Returns the lesser of a and b.
max(a, b)Returns the larger of a and b.
ceil(v)Rounds v up to the nearest integer.
floor(v)Rounds v down to the nearest integer.
round(v)Rounds v to the nearest integer.
signum(v)Returns the sign of v (-1, 0, 1).
sin(a)Returns the sine of a. A full circle is 512.
cos(a)Returns the cosine of a. A full circle is 512.
tan(a)Returns the tangent of a.
asin(a)Returns the arc-sine of a.
acos(a)Returns the arc-cosine of a.
atan2(dy, dx)atan2
angleBetween(x0, y0, x1, y1)Returns the angle from (x0, y0) to (x1, y1).


The following functions are available in the Game table. Call using Game.*, not Game:*

addThread(funcname)Pass the name of a global function to run in parallel to the main function.
destroyAll(spriteType)Destroys all sprites of the specified type. Only the following types are allowed: SPRITE_playerShot, SPRITE_enemy, SPRITE_enemyShot.
setBGM(filename)Starts playing the specified background music (MP3 format). Paths should be relative to the game's bgm folder.
playSFX(filename)Plays the named sound file. Searches /TouhouDS/snd and the stage data folder.
setBgScrollSpeed(sx, sy)Changes the background scroll speed. The default values are (0, 1).
endStage()Ends the current stage immediately.


Almost all in-game objects are Sprites (player-controlled characters, bullets, items, enemies, bombs). Sprites have a number of built-in methods, some of these are called from outside LUA.

Externally called methods

init()Called once, the first frame the Sprite is active.
update()Called every frame. You can use yield in this function.
onDestroyed()Called when the Sprite is destroyed. There are some ways a Sprite can be deleted from the game without begin 'destroyed'. There are two common cases of this:
1. If a Sprite leaves the screen.
2. items get collected, not destroyed.
onCollision(spriteType, power, x, y, col1Id, col2Id)Gets executed when a Sprite gets hit by another Sprite. The type, power, x, y that get passed as parameters to this function are those from the other Sprite. col1Id and col2Id are the ID's of the ColNode's invloved or -1 for special collisions.
animator()Called every frame, use this function to update the Sprite's image. You can use yield in this function.

Internally callable methods

Sprites have some other methods that can be used internally by the LUA script.

setPos(x, y)Changes Sprite position
setSpeed(spd)Changes Sprite speed
setSpeedInc(spdi)Every frame, speed += speedInc
setAngle(a)Changes Sprite angle. A full circle is 512.
setAngleInc(ai)Every frame, angle += angleInc
setPower(pwr)Power doubles as both hit points and damage dealer.
Upon collision, s1p' -= s2p and s2p' -= s1p.
setColCircle(id, r)Sets the ColNode with the specified ID to a circle with radius r.
setColSegment(id, autoRotate, dx, dy, thickness)Sets the ColNode with the specified ID to a line segment from (0, 0) to (dx, dy) and thickness r. When autoRotate == true, dx and dy are changed with the drawAngle.
removeColNode(id)Removes the ColNode with the specified ID.
setDrawAngle(dam, angle)Changes rotation (mode) of the Sprite's image. DAM_auto automatically changes drawAngle to the Sprite's angle each frame (ignores the second arg), DAM_manual sets drawAngle to angle, DAM_rotate increases drawAngle by angle.
setDrawSize(w, h)Changes the draw size of the sprite. Negative sizes produce a mirrored image.
setVisible(v)The boolean v toggles visibility. Being invisible disables collisions.
setImage(texType, x, y, w, h)Where texType is a value of the TexType enum and determines the texture to use. x,y,w,h specify a subrect of the texture.
setInvincibleTime(time)An invincible Sprite can't receive damage. time is in frames.
setZ(z)The z value determines the draw order. Sprites with higher values of z are drawn on top.
setDieOutsideBounds(d)Toggles dieOutsideBounds on or off. When true the Sprite is removed once it flies out of the screen.
getX()Returns the x-coordinate of the Sprite.
getY()Returns the y-coordinate of the Sprite.
getSpeed()Returns speed.
getSpeedInc()Returns speedInc.
getAngle()Returns angle.
getAngleInc()Returns angleInc.
getPower()Returns power.
getDrawAngle()Returns the drawAngle (see setDrawAngle()).
getDrawAngleMode()Returns the current drawAngleMode (DAM_auto or DAM_manual).
getDrawWidth()Returns the current draw width (set using setDrawSize() or setImage()).
getDrawHeight()Returns the current draw height (set using setDrawSize() or setImage()).
isVisible()true if visible.
isDestroyed()true if destroyed or otherwise removed from the game.
getInvincibleTime()Returns invincibleTime (in frames).
getZ()Returns z.
getDieOutsideBounds()Returns value of dieOutsideBounds.
advance(dist)Moves forward by dist
advanceSide(dist)Moves sideways by dist
die()Destroys the Sprite
drop(itemType, amount)Where itemType is a value of the ItemType enum. Drops amount number of items of type itemType


A subclass of sprite.

setName(name)Changes the Boss' displayed name.
addSpellcard(funcname, pow, time, name)Adds a spellcard to the boss' list of spellcards. funcname is the name of the method to call when the spellcard starts. pow and name change start power and spellcard time (in frames). name will be displayed as the spellcard name.
onSpellEnd()This method gets called when a spellcard ends. Override its implementation to do something special on spell endings.


A subclass of sprite.

isFocus()Returns true when the player is holding the focus key.
getAttackLevel()Returns an int (0-4) signifying the power level.
getAttackPower1()Returns the suggested power for primary shots.
getAttackPower2()Returns the suggested power for secondary shots.
isButtonPressed(button)button should be a value of the Keys enum. Returns true if that button is pressed.
setBombCooldown(t)Changes the bomb cooldown (while bombCooldown > 0 no other bombs can be used).
bomb()Override this method to change how the player's bombs work.


There exist several types of enumerations in the program. LUA has no native support for enumerations, so the enums here are actually implemented as (tables containing) number constants. For example the expression SpriteType.SPRITE_enemy evaluates to the number "5" in LUA. The fields are also available as globals (SPRITE_enemy is a global with value 5).

C language definitions of enums

enum AngleTarget {

enum ItemType {

enum CharaAnimationType {

enum DrawAngleMode {

enum TextureType {
    TEX_enemy = 0,
    TEX_bullet = 1,
    TEX_bullet2 = 2,
    TEX_item = 3,
    TEX_player = 4,
    TEX_playerFx = 5,
    TEX_explosion = 6,
    TEX_background = 7,
    TEX_boss = 8,

enum SpriteType {
    SPRITE_default = 0,
    SPRITE_remote = 1,
    SPRITE_player = 2,
    SPRITE_playerShot = 3,
    SPRITE_item = 4,
    SPRITE_enemy = 5,
    SPRITE_enemyShot = 6,

enum Keys {
    VK_left = 1,
    VK_right = 2,
    VK_up = 4,
    VK_down = 8,
    VK_fire = 16,
    VK_focus = 32,
    VK_bomb = 64