RMMZ.d.ts

Last updated at

This post contains minimal efforts to use typescript in your rmmz plugins.

0. The Folder Structure

I'd like to put my source code into another folder instead of ./js/plugins. Let's say it is ./src. I'm going to compile ./src/index.ts into ./js/plugins/PluginName.js. So the folder structure look like this:

./package.json
./js
    /plugins
        PluginName.js (generated from ts)
./src
    /index.ts (the entry point)
I uses esbuild to compile the source code. An example build command will be:
esbuild src/index.ts \
    --bundle \
    --format=iife \
    --global-name=PluginName \
    --minify --sourcemap \
    --outfile=js/plugins/PluginName.js

1. allowJs

First of all, a tsconfig.json is necessary to fully enable typescript in project. I'll put it in ./src/tsconfig.json

{
  "include": [".", "../js"],
  "compilerOptions": {
    "noEmit": true,
    "allowJs": true,
    "esModuleInterop": true,
    "lib": ["ESNext", "DOM"]
  }
}

This will help us to find names like Scene_Title. But it can not read Sprite#addChild because these methods are defined in PIXI.js, so let's find these libraries' d.ts and put them in:

2. Dependencies

./package.json
./js
./src
    /types
        /pixi.js.d.ts

Till now, the dependencies are:

rmmz version: 1.2.1
    effekseer: 1.53b
    localforage: 1.7.3
    pako: N/A
    pixi: 5.2.4
    vorbisdecoder: guess from rpg_core

3. Add Missing Types Manually

allowJs is not perfect. It can not know a Function is actually a class. So I have to tell typescript about that. Create a global.d.ts with these stuff:

// src/types/global.d.ts
export { }

declare global {

  interface Array {
    clone(): Array;
    contains(element: T): boolean;
    equals(array: Array): boolean;
    remove(element: T): this;
  }

  interface Math {
    randomInt(max: number): number;
  }

  interface Number {
    clamp(min: number, max: number): number;
    mod(n: number): number;
    padZero(length: number): string;
  }

  interface String {
    contains(string: string): number;
    format(...args: any[]): string;
    padZero(length: number): string;
  }

  class Point extends PIXI.Point { }
  class Rectangle extends PIXI.Rectangle { }
  class Sprite extends PIXI.Sprite { }
  class Tilemap extends PIXI.Container { }
  namespace Tilemap {
    class Layer extends PIXI.Container { }
    class Renderer extends PIXI.ObjectRenderer { }
  }
  class TilingSprite extends PIXI.TilingSprite { }
  class ScreenSprite extends PIXI.Container { }
  // @ts-ignore
  class Window extends PIXI.Container { }
  class WindowLayer extends PIXI.Container { }
  class Weather extends PIXI.Container { }
  class ColorFilter extends PIXI.Filter { }
  class Stage extends PIXI.Container { }
  class Game_Battler extends Game_BattlerBase { }
  class Game_Actor extends Game_Battler { }
  class Game_Enemy extends Game_Battler { }
  class Game_Party extends Game_Unit { }
  class Game_Troop extends Game_Unit { }
  class Game_Character extends Game_CharacterBase { }
  class Game_Player extends Game_Character { }
  class Game_Follower extends Game_Character { }
  class Game_Vehicle extends Game_Character { }
  class Game_Event extends Game_Character { }
  class Scene_Base extends Stage { }
  class Scene_Boot extends Scene_Base { }
  class Scene_Title extends Scene_Base { }
  class Scene_Message extends Scene_Base { }
  class Scene_Map extends Scene_Message { }
  class Scene_MenuBase extends Scene_Base { }
  class Scene_Menu extends Scene_MenuBase { }
  class Scene_ItemBase extends Scene_MenuBase { }
  class Scene_Item extends Scene_ItemBase { }
  class Scene_Skill extends Scene_ItemBase { }
  class Scene_Equip extends Scene_MenuBase { }
  class Scene_Status extends Scene_MenuBase { }
  class Scene_Options extends Scene_MenuBase { }
  class Scene_File extends Scene_MenuBase { }
  class Scene_Save extends Scene_File { }
  class Scene_Load extends Scene_File { }
  class Scene_GameEnd extends Scene_MenuBase { }
  class Scene_Shop extends Scene_MenuBase { }
  class Scene_Name extends Scene_MenuBase { }
  class Scene_Debug extends Scene_MenuBase { }
  class Scene_Battle extends Scene_Message { }
  class Scene_Gameover extends Scene_Base { }
  class Sprite_Clickable extends Sprite { }
  class Sprite_Button extends Sprite_Clickable { }
  class Sprite_Character extends Sprite { }
  class Sprite_Battler extends Sprite_Clickable { }
  class Sprite_Actor extends Sprite_Battler { }
  class Sprite_Enemy extends Sprite_Battler { }
  class Sprite_Animation extends Sprite { }
  class Sprite_AnimationMV extends Sprite { }
  class Sprite_Battleback extends TilingSprite { }
  class Sprite_Damage extends Sprite { }
  class Sprite_Gauge extends Sprite { }
  class Sprite_Name extends Sprite { }
  class Sprite_StateIcon extends Sprite { }
  class Sprite_StateOverlay extends Sprite { }
  class Sprite_Weapon extends Sprite { }
  class Sprite_Balloon extends Sprite { }
  class Sprite_Picture extends Sprite_Clickable { }
  class Sprite_Timer extends Sprite { }
  class Sprite_Destination extends Sprite { }
  class Spriteset_Base extends Sprite { }
  class Spriteset_Map extends Spriteset_Base { }
  class Spriteset_Battle extends Spriteset_Base { }
  class Window_Base extends Window { }
  class Window_Scrollable extends Window_Base { }
  class Window_Selectable extends Window_Scrollable { }
  class Window_Command extends Window_Selectable { }
  class Window_HorzCommand extends Window_Command { }
  class Window_Help extends Window_Base { }
  class Window_Gold extends Window_Selectable { }
  class Window_StatusBase extends Window_Selectable { }
  class Window_MenuCommand extends Window_Command { }
  class Window_MenuStatus extends Window_StatusBase { }
  class Window_MenuActor extends Window_MenuStatus { }
  class Window_ItemCategory extends Window_HorzCommand { }
  class Window_ItemList extends Window_Selectable { }
  class Window_SkillType extends Window_Command { }
  class Window_SkillStatus extends Window_StatusBase { }
  class Window_SkillList extends Window_Selectable { }
  class Window_EquipStatus extends Window_StatusBase { }
  class Window_EquipCommand extends Window_HorzCommand { }
  class Window_EquipSlot extends Window_StatusBase { }
  class Window_EquipItem extends Window_ItemList { }
  class Window_Status extends Window_StatusBase { }
  class Window_StatusParams extends Window_StatusBase { }
  class Window_StatusEquip extends Window_StatusBase { }
  class Window_Options extends Window_Command { }
  class Window_SavefileList extends Window_Selectable { }
  class Window_ShopCommand extends Window_HorzCommand { }
  class Window_ShopBuy extends Window_Selectable { }
  class Window_ShopSell extends Window_ItemList { }
  class Window_ShopNumber extends Window_Selectable { }
  class Window_ShopStatus extends Window_StatusBase { }
  class Window_NameEdit extends Window_StatusBase { }
  class Window_NameInput extends Window_Selectable { }
  class Window_NameBox extends Window_Base { }
  class Window_ChoiceList extends Window_Command { }
  class Window_NumberInput extends Window_Selectable { }
  class Window_EventItem extends Window_ItemList { }
  class Window_Message extends Window_Base { }
  class Window_ScrollText extends Window_Base { }
  class Window_MapName extends Window_Base { }
  class Window_BattleLog extends Window_Base { }
  class Window_PartyCommand extends Window_Command { }
  class Window_ActorCommand extends Window_Command { }
  class Window_BattleStatus extends Window_StatusBase { }
  class Window_BattleActor extends Window_BattleStatus { }
  class Window_BattleEnemy extends Window_Selectable { }
  class Window_BattleSkill extends Window_SkillList { }
  class Window_BattleItem extends Window_ItemList { }
  class Window_TitleCommand extends Window_Command { }
  class Window_GameEnd extends Window_Command { }
  class Window_DebugRange extends Window_Selectable { }
  class Window_DebugEdit extends Window_Selectable { }

}

4. The End

That's all. There're something we are missing: