Skyrim Special Edition

File information

Last updated

Original upload

Created by

Thiago

Uploaded by

SkyrimThiago

Virus scan

Safe to use

Tags for this mod

About this mod

This mod does nothing on its own however it allows modders to create new forms when the game is already running, also these forms will be persisted both on the save game and on a cache file

Requirements
Permissions and credits
Changelogs
Observations:

⚠️When updating this mod to the latest version, if there are drastic changes to how the forms are serialized, it will be necessary to delete the DynamicPersistentFormsCache.bin in the skyrim root folder (if it was created). You will also need to not use saves with older versions of this mod, or disable this mod on your mod manager, and make a new save, then enable this mod again (This process will delete all your dynamic forms but will keep the game stable). Otherwise, you might experience instability, ctd or infinity loading screens.

The esp file is required and it cannot be merged, renamed or turned light otherwise this mod will not work

This mod has been toughly tested and should be safe to switch between different playthroughs, but it is not safe to add or remove mods during a playthrough as it always have not been.

If the forms loaded are incompatible, with the forms stored in the current save, the game will reload upon detecting it to update the forms. (For example, by switching between two different playthroughs). It will do so by killing the player, if you for example use a perma death or alternative death mod you should keep that in mind.

Added papyrus functions:
Spoiler:  
Show
scriptName DynamicPersistentForms hidden
; Creates a new form that is a copy of given base form, changes to that form will be persisted in the save game.
Form function Create(Form item) global native
; Dispose a form that was created using the previous function.
function Dispose(Form item) global native 
;Tracks a form that was not created using this mod, all changes made to it will be persisted on the save game
function Track(Form item) global native
;Un-tracks a form that was not created using this mod, all changes made to it will no longer be persisted on the save game
function UnTrack(Form item) global native
; Modify forms
function AddMagicEffect(Form item, MagicEffect effect, float magnitude, int area, int duration, float cost) global native
function ClearMagicEffects(Form item) global native
function CopyMagicEffects(Form from, Form to) global native
function CopyAppearance(Form source, Form target) global native
function SetSpellTomeSpell(Book target, Spell teaches) global native
function SetSpellAutoCalculate(Spell spell, bool value) global native
function SetSpellCostOverride(Spell spell, int value) global native
function SetSpellChargeTime(Spell spell, float value) global native
function SetSpellCastDuration(Spell spell, int value) global native
function SetSpellRange(Spell spell, int value) global native
function SetSpellCastingPerk(Spell spell, Perk value) global native
function SetEnchantmentAutoCalculate(Enchantment enchantment, bool value) global native
function SetEnchantmentChargeOverride(Enchantment enchantment, int value) global native
function SetEnchantmentCostOverride(Enchantment enchantment, int value) global native
function SetEnchantmentChargeTime(Enchantment enchantment, float value) global native
function SetAmmoDamage(Ammo ammo, float damage) global native
function SetAmmoProjectile(Ammo ammo, Projectile projectile) global native
; None = 0
; Petty = 1
; Lesser = 2
; Common = 3
; Greater = 4
; Grand = 5
function SetSoulGemCapacity(SoulGem gem, int capacity) global native
function SetSoulGemCurrentSoul(SoulGem gem, int capacity) global native
function LinkSoulGems(SoulGem empty, SoulGem filled) global native


Usage:

For you to implement this mod, I believe you need to write scripts outside creation kit, here is a nice video made by Skyrim Scripting that I found that teaches you how to do that:
Spoiler:  
Show
Examples:
Spoiler:  
Show


Flora and LeveledItem (New)
Spoiler:  
Show
scriptName FC_FloraScript extends Quest

Flora Property FloraSource Auto
LeveledItem Property IngredientSource Auto
Ingredient Property IngredientItem Auto

Event OnInit()
RegisterForSingleUpdate(2)
EndEvent

Event OnUpdate()
Flora newFlora = DynamicPersistentForms.Create(FloraSource) as Flora
LeveledItem myLeveledItem = DynamicPersistentForms.Create(IngredientSource) as LeveledItem
if(newFlora && myLeveledItem)
myLeveledItem.AddForm(IngredientItem, 1, 10)
newFlora.SetIngredient(myLeveledItem)
newFlora.SetName("My New Dynamic Flora")
Game.GetPlayer().PlaceAtMe(newFlora)
endif
EndEvent

Track Existing Form
Spoiler:  
Show
scriptName FC_TrackScript extends Quest
MagicEffect Property Effect Auto
Enchantment Property MyEnchantment Auto
Armor Property ModifyArmor Auto
Armor Property ModelSource Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    DynamicPersistentForms.Track(ModifyArmor)
    Enchantment newEnchantment = DynamicPersistentForms.Create(MyEnchantment) as Enchantment
    ModifyArmor.SetName("this is a base skyrim item, its changes will persist")
    ModifyArmor.SetArmorRating(100)
    ModifyArmor.SetGoldValue(1003)
    DynamicPersistentForms.ClearMagicEffects(newEnchantment)
    DynamicPersistentForms.AddMagicEffect(newEnchantment, Effect, 100, 100, 1, 0)
    ModifyArmor.SetEnchantment(newEnchantment)
    DynamicPersistentForms.CopyAppearance(ModelSource, ModifyArmor)
    Game.GetPlayer().AddItem(ModifyArmor)
    Game.GetPlayer().AddItem(ModelSource)
EndEvent

Un Track Tracked Form
Spoiler:  
Show
scriptName FC_UnTrackScript extends Quest
MagicEffect Property Effect Auto
Enchantment Property MyEnchantment Auto
Armor Property ModifyArmor Auto
Armor Property ModelSource Auto
bool added = false
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Auto State Default
    Event OnUpdate()
        DynamicPersistentForms.Track(ModifyArmor)
        Enchantment newEnchantment = DynamicPersistentForms.Create(MyEnchantment) as Enchantment
        ModifyArmor.SetName("[this items changes will not persist]")
        ModifyArmor.SetArmorRating(100)
        ModifyArmor.SetGoldValue(1003)
        DynamicPersistentForms.ClearMagicEffects(newEnchantment)
        DynamicPersistentForms.AddMagicEffect(newEnchantment, Effect, 100, 100, 1, 0)
        ModifyArmor.SetEnchantment(newEnchantment)
        DynamicPersistentForms.CopyAppearance(ModelSource, ModifyArmor)
        Game.GetPlayer().AddItem(ModifyArmor)
        Game.GetPlayer().AddItem(ModelSource)
        DynamicPersistentForms.UnTrack(ModifyArmor)
        GotoState("Step")
        RegisterForUpdate(0.1)
    EndEvent
EndState
State Step
    Event OnUpdate()
        if(!added && Game.GetPlayer().IsSneaking())
            added = true
            DynamicPersistentForms.Track(ModifyArmor)
            ModifyArmor.SetArmorRating(100)
            ModifyArmor.SetGoldValue(1003)
            ModifyArmor.SetName("[Now it they will]")
            Game.GetPlayer().AddItem(ModifyArmor)
            UnregisterForUpdate()
        endif
    EndEvent
EndState

Dispose Form Created Using this mod
Spoiler:  
Show
scriptName FC_DisposeScript extends Quest
Armor Property StatsSoruce Auto
Armor newArmor
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
bool added = false
Auto State Start
    Event OnUpdate()
        newArmor = DynamicPersistentForms.Create(StatsSoruce) as Armor
        if(newArmor)
            newArmor.SetName("this item will be deleted")
            Game.GetPlayer().AddItem(newArmor)
            ; You must take care of removing the item from the inventory it is in, however it
            ; will no longer be tracked by this mod
            DynamicPersistentForms.Dispose(newArmor)
        endif
        GotoState("Step")
        RegisterForUpdate(0.1)
    EndEvent
EndState
State Step
    Event OnUpdate()
        if(!added && Game.GetPlayer().IsSneaking())
            Game.GetPlayer().RemoveItem(newArmor)
            added = true
            newArmor = DynamicPersistentForms.Create(StatsSoruce) as Armor
            newArmor.SetName("This item will take its place")
            Game.GetPlayer().AddItem(newArmor)
            UnregisterForUpdate()
        endif
    EndEvent
EndState

New Ammo
Spoiler:  
Show
scriptName FC_AmmoScript extends Quest
Ammo Property StatsSoruce Auto
Ammo Property ModelSource Auto
Projectile Property SetProjectile Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Ammo newAmmo = DynamicPersistentForms.Create(StatsSoruce) as Ammo
    if(newAmmo)
        newAmmo.SetName("My New Dynamic Ammo")
        DynamicPersistentForms.SetAmmoDamage(newAmmo, 100)
        DynamicPersistentForms.SetAmmoProjectile(newAmmo, SetProjectile)
        newAmmo.SetGoldValue(1003)
        DynamicPersistentForms.CopyAppearance(ModelSource, newAmmo)
        Game.GetPlayer().AddItem(newAmmo,100)
    endif
endevent

New Armor
Spoiler:  
Show
scriptName FC_ArmorScript extends Quest
MagicEffect Property Effect Auto
Enchantment Property MyEnchantment Auto
Armor Property StatsSoruce Auto
Armor Property ModelSource Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Armor newArmor = DynamicPersistentForms.Create(StatsSoruce) as Armor
    if(newArmor)
        Enchantment newEnchantment = DynamicPersistentForms.Create(MyEnchantment) as Enchantment
        newArmor.SetName("My New Dynamic Armor")
        newArmor.SetArmorRating(100)
        newArmor.SetGoldValue(1003)
        DynamicPersistentForms.ClearMagicEffects(newEnchantment)
        DynamicPersistentForms.AddMagicEffect(newEnchantment, Effect, 100, 100, 1, 0)
        newArmor.SetEnchantment(newEnchantment)
        DynamicPersistentForms.CopyAppearance(ModelSource, newArmor)
        Game.GetPlayer().AddItem(newArmor)
        Game.GetPlayer().AddItem(StatsSoruce)
        Game.GetPlayer().AddItem(ModelSource)
    endif
EndEvent

New Spell Tome
Spoiler:  
Show
scriptName FC_BookScript extends Quest
Book Property StatsSource Auto
Book Property ModelSource Auto
Spell Property TeachesSpell Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Book newBook = DynamicPersistentForms.Create(StatsSource) as Book
    if(newBook)
        newBook.SetName("My New Dynamic Tome")
        DynamicPersistentForms.SetSpellTomeSpell(newBook, TeachesSpell)
        DynamicPersistentForms.CopyAppearance(ModelSource, newBook)
        Game.GetPlayer().AddItem(newBook)
        Game.GetPlayer().AddItem(StatsSource)
        Game.GetPlayer().AddItem(ModelSource)
    endif
EndEvent

New Bow
Spoiler:  
Show
scriptName FC_BowScript extends Quest
MagicEffect Property Effect Auto
Weapon Property StatsSoruce Auto
Weapon Property ModelSource Auto
Enchantment Property MyEnchantment Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Weapon newWeapon = DynamicPersistentForms.Create(StatsSoruce) as Weapon
    if(newWeapon)
        Enchantment newEnchantment = DynamicPersistentForms.Create(MyEnchantment) as Enchantment
        newWeapon.SetName("My New Dynamic Bow")
        newWeapon.SetBaseDamage(100)
        newWeapon.SetSpeed(newWeapon.GetSpeed()*2.0)
        newWeapon.SetGoldValue(1003)
        newWeapon.SetReach(100)
        DynamicPersistentForms.ClearMagicEffects(newEnchantment)
        DynamicPersistentForms.AddMagicEffect(newEnchantment, Effect, 100, 100, 1, 0)
        newWeapon.SetEnchantment(newEnchantment)
        newWeapon.SetEnchantmentValue(100)
        DynamicPersistentForms.CopyAppearance(ModelSource, newWeapon)
        Game.GetPlayer().AddItem(newWeapon)
    endif
EndEvent

New Ingredient
Spoiler:  
Show
scriptName FC_IngredientScript extends Quest
Ingredient Property StatsSource Auto
Ingredient Property ModelSource Auto
Ingredient Property EffectSource Auto
MagicEffect Property Effect Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Ingredient newIngredient = DynamicPersistentForms.Create(StatsSource) as Ingredient
    if(newIngredient)
        newIngredient.SetName("My New Dynamic Ingredient")
        DynamicPersistentForms.ClearMagicEffects(newIngredient)
        DynamicPersistentForms.CopyMagicEffects(EffectSource, newIngredient)
        DynamicPersistentForms.CopyAppearance(ModelSource, newIngredient)
        Game.GetPlayer().AddItem(newIngredient,5)
        Game.GetPlayer().AddItem(StatsSource,5)
        Game.GetPlayer().AddItem(ModelSource,5)
        Game.GetPlayer().AddItem(EffectSource,5)
    endif
EndEvent

New Misc Item
Spoiler:  
Show
scriptName FC_MiscItemScript extends Quest
MiscObject Property StatsSoruce Auto
MiscObject Property ModelSource Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    MiscObject newMiscObject = DynamicPersistentForms.Create(StatsSoruce) as MiscObject
    if(newMiscObject)
        newMiscObject.SetName("My New Dynamic Misc Item")
        newMiscObject.SetGoldValue(1003)
        DynamicPersistentForms.CopyAppearance(ModelSource, newMiscObject)
        Game.GetPlayer().AddItem(newMiscObject)
        Game.GetPlayer().AddItem(StatsSoruce)
        Game.GetPlayer().AddItem(ModelSource)
    endif
EndEvent

New Potion
Spoiler:  
Show
scriptName FC_PotionScript extends Quest
Potion Property StatsSource Auto
Potion Property ModelSource Auto
MagicEffect Property Effect Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Potion newPotion = DynamicPersistentForms.Create(StatsSource) as Potion
    if(newPotion)
        newPotion.SetName("My New Dynamic Potion")
        DynamicPersistentForms.ClearMagicEffects(newPotion)
        DynamicPersistentForms.AddMagicEffect(newPotion, Effect, 100, 100, 1, 0)
        DynamicPersistentForms.CopyAppearance(ModelSource, newPotion)
        Game.GetPlayer().AddItem(newPotion,5)
        Game.GetPlayer().AddItem(StatsSource,5)
        Game.GetPlayer().AddItem(ModelSource,5)
    endif
EndEvent

New Scroll
Spoiler:  
Show
scriptName FC_ScrollScript extends Quest
MagicEffect Property EffectModel Auto
MagicEffect Property EffectBase Auto
Scroll Property StatsSource Auto
Scroll Property ModelSource Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Scroll newScroll = DynamicPersistentForms.Create(StatsSource) as Scroll
    MagicEffect newEffect = DynamicPersistentForms.Create(EffectBase) as MagicEffect
    if(newScroll && newEffect)
        newScroll.SetName("My New Dynamic Scroll")
        DynamicPersistentForms.ClearMagicEffects(newScroll)
        DynamicPersistentForms.AddMagicEffect(newScroll, newEffect, 100, 100, 1, 0)
        DynamicPersistentForms.CopyAppearance(ModelSource, newScroll)
        DynamicPersistentForms.CopyAppearance(EffectModel, newEffect)
        Game.GetPlayer().AddItem(newScroll,5)
        Game.GetPlayer().AddItem(StatsSource,5)
        Game.GetPlayer().AddItem(ModelSource,5)
    endif
EndEvent

New Soul Gem
Spoiler:  
Show
scriptName FC_SoulGemScript extends Quest
SoulGem Property BaseEmptySoulGem Auto
SoulGem Property BaseFilledSoulGem Auto
MiscObject Property AppearenceSource Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    SoulGem newEmptySoulGem = DynamicPersistentForms.Create(BaseEmptySoulGem) as SoulGem
    SoulGem newFilledSoulGem = DynamicPersistentForms.Create(BaseEmptySoulGem) as SoulGem
    if(newEmptySoulGem&&newFilledSoulGem)
        newEmptySoulGem.SetName("My New Dynamic Soul Gem")
        newEmptySoulGem.SetGoldValue(1003)
        newFilledSoulGem.SetName("My New Dynamic Soul Gem")
        newFilledSoulGem.SetGoldValue(1003)
        DynamicPersistentForms.SetSoulGemCapacity(newEmptySoulGem, 2)
        DynamicPersistentForms.SetSoulGemCapacity(newFilledSoulGem, 2)
        DynamicPersistentForms.SetSoulGemCurrentSoul(newFilledSoulGem, 2)
        DynamicPersistentForms.LinkSoulGems(newEmptySoulGem, newFilledSoulGem)
        DynamicPersistentForms.CopyAppearance(AppearenceSource, newEmptySoulGem)
        DynamicPersistentForms.CopyAppearance(AppearenceSource, newFilledSoulGem)
        Game.GetPlayer().AddItem(newEmptySoulGem)
        Game.GetPlayer().AddItem(newFilledSoulGem)
    endif
EndEvent

New Spell
Spoiler:  
Show
scriptName FC_SpellScript extends Quest
MagicEffect Property EffectModel Auto
MagicEffect Property EffectBase Auto
Spell Property StatsSource Auto
Spell Property ModelSource Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Spell newSpell = DynamicPersistentForms.Create(StatsSource) as Spell
    MagicEffect newEffect = DynamicPersistentForms.Create(EffectBase) as MagicEffect
    if(newSpell && newEffect)
        newSpell.SetName("My New Dynamic Spell")
        DynamicPersistentForms.SetSpellCostOverride(newSpell, 1000)
        DynamicPersistentForms.SetSpellChargeTime(newSpell,5)
        ; DynamicPersistentForms.SetSpellAutoCalculate(newSpell, true); Set to true to disable override
        DynamicPersistentForms.ClearMagicEffects(newSpell)
        DynamicPersistentForms.AddMagicEffect(newSpell, newEffect, 100, 100, 1, 100)
        DynamicPersistentForms.CopyAppearance(ModelSource, newSpell)
        DynamicPersistentForms.CopyAppearance(EffectModel, newEffect)
        Game.GetPlayer().AddSpell(newSpell)
        Game.GetPlayer().AddSpell(StatsSource)
        Game.GetPlayer().AddSpell(ModelSource)
    endif
EndEvent

New Staff
Spoiler:  
Show
scriptName FC_StaffScript extends Quest
MagicEffect Property Effect Auto
Weapon Property StatsSoruce Auto
Weapon Property ModelSource Auto
Enchantment Property MyEnchantment Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Weapon newStaff = DynamicPersistentForms.Create(StatsSoruce) as Weapon
    if(newStaff)
        Enchantment newEnchantment = DynamicPersistentForms.Create(MyEnchantment) as Enchantment
        newStaff.SetName("My New Dynamic Staff")
        newStaff.SetGoldValue(1003)
        DynamicPersistentForms.ClearMagicEffects(newEnchantment)
        DynamicPersistentForms.AddMagicEffect(newEnchantment, Effect, 100, 100, 1, 0)
        newStaff.SetEnchantmentValue(1000)
        newStaff.SetEnchantment(newEnchantment)
        DynamicPersistentForms.CopyAppearance(ModelSource, newStaff)
        Game.GetPlayer().AddItem(newStaff)
        Game.GetPlayer().AddItem(StatsSoruce)
        Game.GetPlayer().AddItem(ModelSource)
    endif
EndEvent

New Weapon
Spoiler:  
Show
scriptName FC_WeaponScript extends Quest
MagicEffect Property Effect Auto
Weapon Property StatsSoruce Auto
Weapon Property ModelSource Auto
Enchantment Property MyEnchantment Auto
Event OnInit()
    RegisterForSingleUpdate(2)
EndEvent
Event OnUpdate()
    Weapon newWeapon = DynamicPersistentForms.Create(StatsSoruce) as Weapon
    if(newWeapon)
        Enchantment newEnchantment = DynamicPersistentForms.Create(MyEnchantment) as Enchantment
        newWeapon.SetName("My New Dynamic Weapon")
        newWeapon.SetBaseDamage(100)
        newWeapon.SetSpeed(newWeapon.GetSpeed()*2.0)
        newWeapon.SetGoldValue(1003)
        newWeapon.SetReach(100)
        
        DynamicPersistentForms.ClearMagicEffects(newEnchantment)
        DynamicPersistentForms.AddMagicEffect(newEnchantment, Effect, 100, 100, 1, 0)
        newWeapon.SetEnchantment(newEnchantment)
        newWeapon.SetEnchantmentValue(9)
        DynamicPersistentForms.SetEnchantmentChargeOverride(newEnchantment, 6)
        DynamicPersistentForms.SetEnchantmentCostOverride(newEnchantment, 3)
        ; DynamicPersistentForms.SetEnchantmentAutoCalculate(newEnchantment, true); Set to true to disable override
        DynamicPersistentForms.CopyAppearance(ModelSource, newWeapon)
        Game.GetPlayer().AddItem(newWeapon)
    endif
EndEvent

Credits
Spoiler:  
Show
RedxYeti: Did a lot of testing and bug reports. Also helped me figure out the reason behind some bugs.
Quantumyilmaz: For sharing with me some of his knowledge about skse

Source Codes


Here are some of my other mods
Spoiler:  
Show
For players:
Teleportation spell: You can set up to 30 named anchors and then teleport to them whenever you want, you can also go back to your original location
Magic Storage: You have a magical storage that you can access via a spell, however it reduces your health by one tent of its items weight (configurable)
Reusable Consumables: A work in progress mod that allows you to use consumables more than once.
For modders:
Atronach Forge Fix: Fixes the script to handle recipes in a way that you can use the same item more than one time
BBCode Papyrus Coloring (Nexus forums): You can color your own papyrus code snippets with this web app