This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tutorial:intro-to-elden-ring-emevd [2025/02/25 15:23] – admin | tutorial:intro-to-elden-ring-emevd [2025/02/27 00:33] (current) – [Model names] admin | ||
|---|---|---|---|
| Line 26: | Line 26: | ||
| * Use DSMapStudio ([[https:// | * Use DSMapStudio ([[https:// | ||
| * Use WitchyBND ([[https:// | * Use WitchyBND ([[https:// | ||
| - | * Use various [[er-reference:main | Elden Ring reference pages]], also listed below under "entry points" | + | * Use various [[er-refmat:main| Elden Ring reference pages]], also listed below under "entry points" |
| Of course, also use an event script editor. These are available for Elden Ring: | Of course, also use an event script editor. These are available for Elden Ring: | ||
| Line 65: | Line 65: | ||
| Don't forget! If something isn't happening in the game when you expect it, make sure your changes are even recognized by the game in the first place. This is best accomplished by simple "is it on" checks which do something conspicuous. For instance, in DarkScript3: | Don't forget! If something isn't happening in the game when you expect it, make sure your changes are even recognized by the game in the first place. This is best accomplished by simple "is it on" checks which do something conspicuous. For instance, in DarkScript3: | ||
| - | < | + | < |
| DisplayBanner(TextBannerType.DutyFulfilled); | DisplayBanner(TextBannerType.DutyFulfilled); | ||
| </ | </ | ||
| - | < | + | < |
| AwardItemLot(997200); | AwardItemLot(997200); | ||
| </ | </ | ||
| Line 90: | Line 90: | ||
| Let's start with some shorter events in the game, before getting into longer ones which pull together a ton of game systems. An event script defines many events which run while the script is loaded. You can think of these like functions in a programming language, each identified by a unique number. An event must be initialized to have any effect in the game at all. All events run in parallel, executing one instruction after the next from top to bottom, sometimes skipping optional instructions or stopping altogether until some condition is met. | Let's start with some shorter events in the game, before getting into longer ones which pull together a ton of game systems. An event script defines many events which run while the script is loaded. You can think of these like functions in a programming language, each identified by a unique number. An event must be initialized to have any effect in the game at all. All events run in parallel, executing one instruction after the next from top to bottom, sometimes skipping optional instructions or stopping altogether until some condition is met. | ||
| - | For how loading works, that's a bit complicated. See the [[[er-refmat: | + | For how loading works, that's a bit complicated. See the [[er-refmat: |
| How this works in the event script itself is that there are special events called constructors which get automatically initialized when an event script is loaded. These are events with low ids like 0 and 50. As you can see, these constructor events are responsible for initializing every other event in the file, and a few others too. | How this works in the event script itself is that there are special events called constructors which get automatically initialized when an event script is loaded. These are events with low ids like 0 and 50. As you can see, these constructor events are responsible for initializing every other event in the file, and a few others too. | ||
| Line 96: | Line 96: | ||
| For instance, take a look at m14_00_00_00.emevd.dcx, | For instance, take a look at m14_00_00_00.emevd.dcx, | ||
| - | < | + | < |
| $Event(0, Default, function() { | $Event(0, Default, function() { | ||
| RegisterBonfire(14000002, | RegisterBonfire(14000002, | ||
| Line 113: | Line 113: | ||
| You can Ctrl+Click on 14002080 in the above event (within DarkScript3) to see the event' | You can Ctrl+Click on 14002080 in the above event (within DarkScript3) to see the event' | ||
| - | < | + | < |
| $Event(14002080, | $Event(14002080, | ||
| EndIf(!PlayerIsInOwnWorld()); | EndIf(!PlayerIsInOwnWorld()); | ||
| Line 138: | Line 138: | ||
| Here is another event in Stormveil Castle (m10_00_00_00) which has two waits in it. It includes a RestartEvent, | Here is another event in Stormveil Castle (m10_00_00_00) which has two waits in it. It includes a RestartEvent, | ||
| - | < | + | < |
| $Event(10002460, | $Event(10002460, | ||
| WaitFor(TimeOfDayInRange(19, | WaitFor(TimeOfDayInRange(19, | ||
| Line 158: | Line 158: | ||
| The key thing to note here is '' | The key thing to note here is '' | ||
| - | < | + | < |
| $Event(18002860, | $Event(18002860, | ||
| if (EventFlag(18000850)) { | if (EventFlag(18000850)) { | ||
| Line 197: | Line 197: | ||
| We'll get to the second case when we talk about parameters, but a quick example of the first use case is as follows. This event kills the player if they' | We'll get to the second case when we talk about parameters, but a quick example of the first use case is as follows. This event kills the player if they' | ||
| - | < | + | < |
| $Event(xxxxxxxx, | $Event(xxxxxxxx, | ||
| WaitFor(PlayerHasArmorEquipped(ArmorType.Legs, | WaitFor(PlayerHasArmorEquipped(ArmorType.Legs, | ||
| Line 233: | Line 233: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002860, | $Event(13002860, | ||
| if (EventFlag(13000850)) { | if (EventFlag(13000850)) { | ||
| Line 290: | Line 290: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002860, | $Event(13002860, | ||
| // This first block is executed only when the boss defeat flag is set. Otherwise, skip it. | // This first block is executed only when the boss defeat flag is set. Otherwise, skip it. | ||
| Line 427: | Line 427: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002850, | $Event(13002850, | ||
| EndIf(EventFlag(13000850)); | EndIf(EventFlag(13000850)); | ||
| Line 448: | Line 448: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002850, | $Event(13002850, | ||
| // If they' | // If they' | ||
| Line 501: | Line 501: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002861, | $Event(13002861, | ||
| EndIf(EventFlag(13000850)); | EndIf(EventFlag(13000850)); | ||
| Line 511: | Line 511: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002861, | $Event(13002861, | ||
| // As usual, ignore the rest if the boss is already defeated. | // As usual, ignore the rest if the boss is already defeated. | ||
| Line 536: | Line 536: | ||
| The next event starts out like this: | The next event starts out like this: | ||
| - | < | + | < |
| $Event(13002890, | $Event(13002890, | ||
| ... | ... | ||
| Line 544: | Line 544: | ||
| Note the extra X0_4, X4_4, and so on. Remember that all events must be initialized in order to be active. In this case, there is extra data passed in during initialization! If you Ctrl+Click on the event id here, you can hop to the initializations, | Note the extra X0_4, X4_4, and so on. Remember that all events must be initialized in order to be active. In this case, there is extra data passed in during initialization! If you Ctrl+Click on the event id here, you can hop to the initializations, | ||
| - | < | + | < |
| InitializeEvent(0, | InitializeEvent(0, | ||
| InitializeEvent(1, | InitializeEvent(1, | ||
| Line 554: | Line 554: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002890, | $Event(13002890, | ||
| EndIf(!PlayerIsInOwnWorld()); | EndIf(!PlayerIsInOwnWorld()); | ||
| Line 573: | Line 573: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| // X0_4: The event flag to set indicating that X4_4 should be respawned | // X0_4: The event flag to set indicating that X4_4 should be respawned | ||
| // X4_4: Entity id of the godskin to respawn | // X4_4: Entity id of the godskin to respawn | ||
| Line 621: | Line 621: | ||
| It respawns a godskin when it has been requested by the other alive godskin. | It respawns a godskin when it has been requested by the other alive godskin. | ||
| - | < | + | < |
| InitializeEvent(0, | InitializeEvent(0, | ||
| InitializeEvent(1, | InitializeEvent(1, | ||
| Line 627: | Line 627: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002891, | $Event(13002891, | ||
| EndIf(!PlayerIsInOwnWorld()); | EndIf(!PlayerIsInOwnWorld()); | ||
| Line 645: | Line 645: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| // X0_4: The event flag to check indicating that X4_4 should be respawned | // X0_4: The event flag to check indicating that X4_4 should be respawned | ||
| // X4_4: Generator id (not entity id!) of the godskin to respawn | // X4_4: Generator id (not entity id!) of the godskin to respawn | ||
| Line 702: | Line 702: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002892, | $Event(13002892, | ||
| EndIf(!PlayerIsInOwnWorld()); | EndIf(!PlayerIsInOwnWorld()); | ||
| Line 734: | Line 734: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(13002892, | $Event(13002892, | ||
| // Similar checks for host-only and for avoiding respawn after boss defeat. | // Similar checks for host-only and for avoiding respawn after boss defeat. | ||
| Line 801: | Line 801: | ||
| This event allows a host player to traverse a boss fog gate, and sets a flag once they do. Summoned players use a separate event 9005801 to traverse the fog gate after the host does, meaning when flag X12_4 here is set. They also run this event, but it has no effect for them. | This event allows a host player to traverse a boss fog gate, and sets a flag once they do. Summoned players use a separate event 9005801 to traverse the fog gate after the host does, meaning when flag X12_4 here is set. They also run this event, but it has no effect for them. | ||
| - | < | + | < |
| InitializeCommonEvent(0, | InitializeCommonEvent(0, | ||
| InitializeCommonEvent(0, | InitializeCommonEvent(0, | ||
| Line 808: | Line 808: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(9005800, | $Event(9005800, | ||
| if (!EventFlag(X0_4)) { | if (!EventFlag(X0_4)) { | ||
| Line 871: | Line 871: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| // X0_4: Boss defeat event flag | // X0_4: Boss defeat event flag | ||
| // X4_4: Entity id for the fog gate asset | // X4_4: Entity id for the fog gate asset | ||
| Line 1022: | Line 1022: | ||
| So the above event allows you pass through a solid wall using RotateCharacter, | So the above event allows you pass through a solid wall using RotateCharacter, | ||
| - | < | + | < |
| InitializeCommonEvent(0, | InitializeCommonEvent(0, | ||
| InitializeCommonEvent(0, | InitializeCommonEvent(0, | ||
| Line 1032: | Line 1032: | ||
| This event controls when the fog gate shows up and disappears using the ChangeAssetEnableState and CreateObjectfollowingSFX commands. I won't explain the details of the event here, as it behaves in a bunch of different complicated ways depending on whether you're a host, a summon, or the invader. Still, the arguments are as follows: | This event controls when the fog gate shows up and disappears using the ChangeAssetEnableState and CreateObjectfollowingSFX commands. I won't explain the details of the event here, as it behaves in a bunch of different complicated ways depending on whether you're a host, a summon, or the invader. Still, the arguments are as follows: | ||
| - | < | + | < |
| // X0_4: The boss defeat flag. When this is on, the fog gate does not show up. | // X0_4: The boss defeat flag. When this is on, the fog gate does not show up. | ||
| // X4_4: Entity id for the fog gate asset | // X4_4: Entity id for the fog gate asset | ||
| Line 1055: | Line 1055: | ||
| Here is an example initialization in m14_00_00_00 (Raya Lucaria), which applies to the scholar in the middle of the Cuckoo Church: | Here is an example initialization in m14_00_00_00 (Raya Lucaria), which applies to the scholar in the middle of the Cuckoo Church: | ||
| - | < | + | < |
| InitializeCommonEvent(0, | InitializeCommonEvent(0, | ||
| </ | </ | ||
| Here is another initialization in m30_04_00_00 (Murkwater Catacombs), which applies to an imp waiting to drop down from the ceiling when you approach: | Here is another initialization in m30_04_00_00 (Murkwater Catacombs), which applies to an imp waiting to drop down from the ceiling when you approach: | ||
| - | < | + | < |
| InitializeCommonEvent(0, | InitializeCommonEvent(0, | ||
| </ | </ | ||
| Line 1067: | Line 1067: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| $Event(90005200, | $Event(90005200, | ||
| EndIf(SpecialStandbyEndedFlag(X0_4)); | EndIf(SpecialStandbyEndedFlag(X0_4)); | ||
| Line 1155: | Line 1155: | ||
| <hidden onHidden=" | <hidden onHidden=" | ||
| - | < | + | < |
| // X0_4: Entity id of the enemy | // X0_4: Entity id of the enemy | ||
| // X4_4: Animation id which loops while it's waiting for the trigger | // X4_4: Animation id which loops while it's waiting for the trigger | ||
| Line 1324: | Line 1324: | ||
| ==== Map ids ==== | ==== Map ids ==== | ||
| * Where it's located: Maps are how most of the game world is split up, so finding a map id is critical to being able to search for something in a particular MSB (in '' | * Where it's located: Maps are how most of the game world is split up, so finding a map id is critical to being able to search for something in a particular MSB (in '' | ||
| - | * How to browse it: Use [[er-refmat: | + | * How to browse it: Use [[er-refmat: |
| * How to use it: Open the files in a map/event editor! | * How to use it: Open the files in a map/event editor! | ||
| * Example: You want to view/edit something in Roundtable Hold. Find that it's m11_10_00_00 in the map list, and open those files in DarkScript3/ | * Example: You want to view/edit something in Roundtable Hold. Find that it's m11_10_00_00 in the map list, and open those files in DarkScript3/ | ||
| Line 1332: | Line 1332: | ||
| * How to browse it: Use [[https:// | * How to browse it: Use [[https:// | ||
| * How to use it: In addition to or instead of the above reference, you can also use the [[https:// | * How to use it: In addition to or instead of the above reference, you can also use the [[https:// | ||
| - | * Example: You want to find Radahn. Use above references to see that he's c4730, and that his full name is m60_52_38_00-c4730_9002, | + | * Example: You want to find Radahn. Use above references to see that he's c4730, and that his full name is m60_52_38_00-c4730_9002, |
| ==== Entity ids ==== | ==== Entity ids ==== | ||