Modding: Basics

提供:Noita Wiki
ナビゲーションに移動 検索に移動
This article is a stub. You can help Noita Wiki by expanding it.

ナビゲーション
基本事項
最初の一歩 • Data.wak • Moddingをはじめるには • Lua Scripting • Useful Tools
Guides
Audio • Enemies • Environments (Fog of War) • Image Emitters • Materials • Perks • Special Behaviors • Spells • Spritesheets • Steam Workshop • Using CMake
Components/Entities
Component Documentation • Enums • List of all tags • Special Tags • Tags System • Update Order
Lua Scripting
Lua API • Utility Scripts
Other Information
Enemy Information Table • Magic Numbers • Sound Events • Spell IDs • Perk IDs • 資材のID

Noita MODの基本概念 (エンティティコンポーネントシステム、ディレクトリ構造、Luaスクリプトファイルとの関係性など) を簡単に説明します。

Modのインストール場所

MODを設置できる箇所は2個所あります。

  • Noita/mods/ - 手動でダウンロードしたMODや、開発中のMODを格納するフォルダとなります。
  • steamapps/workshop/content/881100/ - Steamワークショップ経由でダウンロードしたMODを格納するフォルダとなります。

MODのディレクトリ構造

よくあるMOD構造を例として提示しています。

myAwesomeMod/
├── data/
│   └── enemies_gfx/
│       └── player.png
├── files/
│   └── my_custom_script.lua
├── init.lua
└── mod.xml

各ファイルやフォルダについて、細かく見ていきます。

  • myAwesomeMod/
    • このフォルダはルートフォルダとなります。後でフォルダ名をコード全体で参照する必要があるので、フォルダ名は慎重に決めてください。**この名前はNoita上で表示されるMOD名ではないことに注意してください**
  • data/
    • このフォルダはdata_wak_unpack.batを使って解凍したNoitaのデータファイルのルートフォルダを示しています。MOD側でNoita側のデータをオーバーライドする場合に利用します。オーバーライドする場合は、下のNoitaのデータファイルと同じディレクトリ構造、ファイル名を指定してください。
  • enemies_gfx/
    • 敵と味方のスプライトシートをまとめたフォルダとなります。
  • player.png
    • プレイヤーのアニメーション用スプライトシートです。このMODをONにすると、プレイヤーがMOD側で用意したplayer.png内のスプライトシートに差し替えられます。
  • files/
    • このフォルダーは作成するMODで利用する全てのカスタム用データ(スクリプトデータ、画像ファイルetc..)を設置するためのフォルダとなります。既存のアセットデータを直接置き換えたくない場合に使用します。
    • 殆どの場合、こちらを使用すると思われます。data内でオーバーライドするのではなく、files内で自身のアセットデータを用意してした方がMOD間での互換性も上がるので、極力こちらを利用した方が良いと思われます。
  • my_custom_script.lua
    • 自身で作成するオリジナルのスクリプトファイルとなります。何でも実行でき、どこからでも呼び出すことができます。実際にMODを作る際には、もう少し良い名前で作成してください。
  • init.lua
    • このスクリプトにはNoita側からのイベント(世界の初期化後、プレイヤースポーン時)に応じて自動的にcallされる関数(Hook)がいくつか用意されています。
    • 最初はこのスクリプトファイルを編集して、"Hello World"するところから始めるのが良いでしょう。
  • mod.xml
    • MODのメタデータを定義するxmlファイルとなります。名前、説明、その他の設定が含まれています。

別のパスにあるファイルの参照

上でお伝えした通り、フォルダ data/files/ の挙動は大きく異なっています。そのため、MOD内でのファイルの参照方法も異なります。 data/内は基本的に、直接参照できるNoita内の独自の仮想ファイルシステムと考えることができますが、それ以外のものには完全なMODフォルダからのパスが含まれている必要があります。 上記を元に例を出すと

-- Partial path for data files (also when overwritten and even if it's not included in *your* own mod)
dofile_once("data/scripts/lib/utilities.lua")

-- Full path for own scripts
dofile_once("mods/myAwesomeMod/files/scripts/my_custom_script.lua")

XMLでパスを利用しようとするとき(スプライトシートや放射物、エフェクト等の読み込み)も、全く同じようにパスを記述する必要があります。

エンティティコンポーネントシステムの基本

エンティティは、以下のルールに基づいて作成されています。

  • 任意の数のコンポーネントを1つのエンティティ含めるられます
  • 子エンティティを持てます
  • 独自のコンポーネントを定義できます
  • 他のエンティティから機能を継承できます
  • 名前は1つだけ付けられます
  • 複数のタグを付けられます

ゲームファイル内にあるエンティティファイルを見てみましょう data/entities/props/banner.xml

<Entity tags="prop">

  <VelocityComponent />

  <SimplePhysicsComponent />

  <SpriteComponent
    z_index="1"
    image_file="data/props_gfx/banner.xml"
    offset_x="0"
    offset_y="0"
  ></SpriteComponent>
</Entity>

上記のエンティティはゲーム内で最もシンプルなエンティティで、3つのコンポーネントのみで構成されています。 ゲーム内でこのエンティティを生成した場合、特別な機能は持たず、単純なアニメーションの旗が地面に設置されます。

  • VelocityComponent は物理を扱うものには必須のコンポーネントとなります。このコンポーネントでは様々なものを定義できますが(エンティティに対しての重力設定など)、ここでは単にデフォルト値が設定されています。Componentで定義されている全ての設定値はcomponent_documentation.txtで確認できます。
  • SimplePhysicsComponent はエンティティにとてもシンプルな物理特性を与えます。常に落ちて、壁や地面に止まります。適切な物理オブジェクトが衝突することはなく、蹴ることもできないです。適切な物理演算を行うには PhysicsShapeComponentPhysicsBodyComponentが必要になります。データファイルには、様々な例が数多く用意されています。
  • SpriteComponent は指定されたオフセット値を利用して、画像ファイルをエンティティに設定します。ここではXMLファイルが画像のソースとして定義されています。これは、アニメーション化されたスプライトをエンティティに追加するときに必要となります。スプライトが静止画の場合は、ここで画像ファイルを直接参照することもできます。

次に data/props_gfx/banner.xml の画像ファイルを見てみましょう。

<Sprite
  filename="data/props_gfx/banner.png"
  offset_x="12"
  offset_y="30"
  default_animation="stand">

  <!-- stand -->
  <RectAnimation
    name="stand"
    pos_x="0"
    pos_y="0"
    frame_count="7"
    frame_width="32"
    frame_height="32"
    frame_wait="0.11"
    frames_per_row="7"
    loop="1"
  ></RectAnimation>
</Sprite>

これらの個別のメタデータは基本的にエンティティコンポーネントシステムの外部にありますが、他のものと同じXML形式でスプライトのメタデータを定義しています。 このXML内にある要素はコンポーネントでもエンティティでもないため、項目の説明は component_documentation.txtのドキュメントで見つけることができません。

細かく読み解いていきましょう。

  • このファイルで最終的に描画したい実際の画像ファイルを参照します
  • The main <Sprite> element has only one <RectAnimation> child element, it could have multiple of these, one for each animation (normal for any characters)
  • The animation name is "stand", and it's referenced as the default one aswell. The names can be anything, but it has to match with whatever's using them.
  • The frame_* attributes are quite self-explanatory, but basically the most essential part when defining animations. These have to match with the spritesheet in your image file.

You can go take a look at the file data/props_gfx/banner.png, and this all should become fairly obvious.

Creating and deleting entities

There are a multitude of ways in which you can spawn/kill entities. The simplest way is directly with Lua:

  • Spawn with EntityLoad("path/to/entity.xml" , x, y)
  • Delete with EntityKill(entity_id)

Just as an example, other possible spawn/kill places include:

  • ProjectileComponent::spawn_entity can be used to spawn any entity upon projectile collision
  • CameraBoundComponent can be used to limit frequently used entities' spawn rates / distances (eg. enemies, lanterns, ...)
  • LifetimeComponent literally gives an entity a certain time to live
  • DamageModelComponenet enables hitpoints and taking damage for the entity. Entity is killed upon reaching 0 health.
  • ...and many more!

Tags

Entities and components both can have any number of tags attached to them. Tags are a very simple way to categorize one type of "thing", and can be easily created on the fly without any extra definitions. For example, fetching a list of all enemies around the player is this easy: EntityGetWithTag("enemy").

Most tags don't have anything else to them, but there is a group of special tags which have in-engine hard-coded functionality attached to them.

Notes:

  • Entity tags are defined in the tags attribute, while Component tags are defined in the _tags attribute.
  • The engine currently supports only a very limited amount of custom tags, which is global across all mods. This is important to keep in mind for inter-mod compatibilty.
    • Via community testing, the upper limits seem to be currently be about tags=224 and _tags=210
  • The special tags are integral to whole Entity-Component system of Noita, so make sure to read through that page

Entity inheritance

  • Implemented via the Base component
    • Base entity filepath in the file attribute
  • Override base entity components by defining new ones inside the Base element tags
    • When overriding, the Base entity must have the components defined that you are trying to override. Otherwise an error will occur.
  • Your own additions go normally outside the Base element
  • You can inherit from as many Base entities as you like
  • All entity tags will be bunched together

init.lua

The first piece of code that is run for any mod. Includes pre-determined function names you can use for hooking into certain events and provides a place to gather together all your mod's file overrides.

The following bits are taken almost straight from mods/example/init.lua. All of the code is optional, you can include only the parts that you need.

Available function hooks

-- Called in order upon loading a new(?) game:
function OnModPreInit() end
function OnModInit() end
function OnModPostInit() end

-- Called when player entity has been created. Ensures chunks around the player have been loaded & created.
function OnPlayerSpawned(player_entity) end

-- Called when the player dies
function OnPlayerDied( player_entity ) end

-- Called once the game world is initialized. Doesn't ensure any chunks around the player.
function OnWorldInitialized() end

-- Called *every* time the game is about to start updating the world
function OnWorldPreUpdate() end

-- Called *every* time the game has finished updating the world
function OnWorldPostUpdate() end

-- Called when the biome config is loaded.
function OnBiomeConfigLoaded() end

-- The last point where the Mod API is available. After this materials.xml will be loaded.
function OnMagicNumbersAndWorldSeedInitialized() end

-- Called when the game is paused or unpaused.
function OnPausedChanged( is_paused, is_inventory_pause ) end
    
-- Will be called when the game is unpaused, if player changed any mod settings while the game was paused
function OnModSettingsChanged() end

-- Will be called when the game is paused, either by the pause menu or some inventory menus. Please be careful with this, as not everything will behave well when called while the game is paused.
function OnPausePreUpdate() end

Overriding and extending systems

These lines are usually added to the end/beginning of init.lua. This code runs when all mods' filesystems are registered.

-- Basically dofile("mods/mymod/files/actions.lua") will appear at the end of gun_actions.lua
ModLuaFileAppend("data/scripts/gun/gun_actions.lua", "mods/mymod/files/actions.lua")

-- Same, but for potions
ModLuaFileAppend("data/scripts/items/potion.lua", "mods/mymod/files/potion_appends.lua" )

-- Will override some magic numbers using the specified file
ModMagicNumbersFileAdd("mods/mymod/files/magic_numbers.xml")

-- Append your own materials to the game's material list
ModMaterialsFileAdd("mods/mymod/files/custom_materials.xml")

-- Use this to register custom fmod events. Event mapping files can be generated via File -> Export GUIDs in FMOD Studio.
ModRegisterAudioEventMappings("mods/mymod/files/audio_events.txt")

Important and interesting files

Good to go through

magic_numbers.xml

  • A lot of variables to control the behaviour of many aspects of the game and gameplay. From virtual resolution (for controlling the amount of world you see) to the amount of blood animals spill, good to go through.

data/scripts/lib/utilities.lua

  • A lot of utility functions ready-made by Nolla. Includes helpers for a lot of basic 2D platformer math, the ECS and more. Good read through to get an idea how things work and not re-implement basic things many times.

Probably not too useful starting out

genome_relations.csv

  • A table of how all the game's animals (including the player) feel toward eachother.
  • Can be edited freely; eg. make everyone friendly towards the player.

translations/common.csv

  • Includes all the basic translations for the game. Good for cross-linking certain spell names, because most of the text seen in-game is not actually present in the code, but here.
  • Can also be edited freely, if you want to eg. rename/rewrite any spells or parts of the game.

scripts/wang_scripts.csv

  • "Global" biome function registration. Any names defined here are available to all wang tiles and pixel scenes.
  • Note: All biome will still need an implementation for these functions separately.
  • Can be edited freely to add your own.

post_final.frag

  • The "main" OpenGL shader file, can be edited and appended freely to create your own shader effects. Not recommended without a prior experience of programming / shaders.

Lists of interest

  • Materials: data/materials.xml
  • Perks: data/scripts/perks/perk_list.lua
  • Potions: data/scripts/items/potion.lua
  • Spells: data/scripts/gun/gun_actions.lua
  • Status effects: data/scripts/status_effects/status_list.lua
  • See above section on init.lua for how to extend these

Debugging

Noita does not currently have any sort of dedicated IDE / testing environment for development. A lot of the development time will indeed be spent just restarting the game to try out new changes. Below is a list of the most common ways for debugging Noita mods:

  1. The development build noita_dev.exe:
    • Starts with a development console. This is the best way to directly find out any errors in your Lua / XML as they happen.
    • The executable should be located in tools_modding/, but can only be started from the root folder (ie. next to the noita.exe). If you've followed instructions so far, it should already be there.
    • Press F1 to show a list of keybinds. Press F5 to enable most debugging features.
    • Required for seeing print() output in the console, but GamePrint() still works anywhere (rendered in-game on the lower left corner).
    • Note: This is known to decrease performance for many people. So it's totally fine to switch between the two builds frequently.
  2. Logging to file:
    • Enable via specific magic numbers.
    • Or download a nice mod which does this for you: Modworkshop
    • Logs to Noita/logger.txt
  3. CheatGUI Mod:
    • Great for testing gameplay features, without fiddling with any debug features.
    • Spawn items/perks/wands, teleport, increase health, etc. All straight from in-game HUD
    • Download: [Steam Workshop | Github]
  4. Noita also supports the Decoda Lua debugger:
    • Needs separate setup. Instructions found in tools_modding/lua_debugging.txt

Note: The game is supposed to detect when any mod files change and consequently hard-restart the game upon starting a new game, but this is known to not work too reliably currently. Thus for now it's advised to always restart your game entirely via manually exiting / killing the game first.