Difference between revisions of "Loading Level Resources With Lua"

From Journey Modding Wiki
Jump to navigation Jump to search
(Created page. Have tested Trigger/Clump loading quite a bit, everything else is just educated guesses)
 
Line 60: Line 60:
ResolveTriggerNames( game:eventBarn(), game:clumpBarn() )
ResolveTriggerNames( game:eventBarn(), game:clumpBarn() )


--run this to demonstrate that they work, on the same frame you create the triggers: see below for why it's done on same frame
-- these activations aren't necessary to load the triggers, just done on the same frame to demonstrate that they work; see below for why it's done on same frame
 
ActivateTriggerByName( "TextTrigger" )
ActivateTriggerByName( "TextTrigger" )
ActivateTriggerByName( "AnimTrigger" )
ActivateTriggerByName( "AnimTrigger" )
</code>
</code>

Revision as of 02:59, 6 June 2021

This is what has been found so far to add and/or modify level resource objects in the Names table using a Lua script, along with brief descriptions of what these objects do.

Important things to remember

These methods do not actually edit how the game reads an embedded Level_SomeLevel/SomethingInstances.lua , so these changes only last until the level is unloaded.

If you try to reference an object that isn't in the Names table (an object from another level, or one that just doesn't exist, etc) your game will crash. It is not yet known whether your companion's game will crash if you reference an object that only exists in your Names table; this seems unlikely for most objects, but might happen with networked Trigger types.

Although the SomethingInstances.lua's all have each part of their table on its own line, it seems like the entire table needs to be on the same line to run properly in Lua.

The SomethingInstances/etc tables that you construct to load resources into the Names table are usually (but not always) cleared automatically after the functions run, to free up memory.

Triggers

Triggers are various types of events, including events that activate other events. They control basically everything that ever "happens" in a level, apart from basic player actions. The functions in this category are mainly from EventSetter.lua .

Modifying Triggers

To modify existing Triggers, find them in TriggerInstances.lua, define them in the TriggerInstances table with the same format used in that lua, then run the ResolveTriggerNames function. Code "template":

TriggerInstances = { ObjectType = "TriggerInstances", {ObjectName = "the original trigger's ObjectName", GardenerName = "the original GardenerName", Type = "the original Type", Shortcut = "", Vars = { customize the vars however you want } }, { all that same stuff for another trigger }, {and another, etc} }

ResolveTriggerNames( game:eventBarn(), game:clumpBarn() )

Code example - using this in CS will change the music cue when you collect the first symbol at the broken statue, so you hear the start-game cutscene music instead:

TriggerInstances = { ObjectType = "TriggerInstances", {ObjectName = "ed489eebe96121c9de7ccce1d25d6ced", GardenerName = "|PlaySFXTrigger270|PlaySFXTrigger270_G", Type = "PlaySFXTrigger", Shortcut = "", Vars = { bankName = "LvlMus", soundName = "M_0m1", vol = 1} } }

ResolveTriggerNames( game:eventBarn(), game:clumpBarn() )

With this method by itself, if you change the trigger type to a different one than the original, it seems to (sometimes?) not work due to it expecting different data types; it's not yet known how to completely change the trigger type. You might be able to at least change trigger types if the Vars would be the same data types/names - for example if two trigger types both use { var1 = float, var2 = string, var3 = a Clump of Hulls, var4 = boolean } you could possibly switch from one type to the other and change the Var values and it would work; not tested yet.

Creating new Triggers

You can create new triggers basically the same way, by adding the CreateTriggers function:

TriggerInstances = { ObjectType = "TriggerInstances", { ObjectName = "NewTrigger", GardenerName = "NewTrigger_G(this name doesn't matter?)", Type = "whatever type you want", Shortcut = "", Vars = { whatever vars that type of trigger uses } }, {same for more new triggers} }

CreateTriggers( game:eventBarn() )

ResolveTriggerNames( game:eventBarn(), game:clumpBarn() )

For example:

TriggerInstances = { ObjectType = "TriggerInstances", { ObjectName = "TextTrigger", GardenerName = "TextTrigger_G", Type = "DisplayText", Shortcut = "", Vars = {text = "Check this out, I can do a backflip", x = 0, y = 0, duration = 3, fadeTime = 0.5 } }, { ObjectName = "AnimTrigger", GardenerName = "AnimTrigger_G", Type = "PlayDudeAnim", Shortcut = "", Vars = { animName = "HitBodyMAir", clearAnimQueue = true, useLocal = true} } }

CreateTriggers( game:eventBarn() )

ResolveTriggerNames( game:eventBarn(), game:clumpBarn() )

-- these activations aren't necessary to load the triggers, just done on the same frame to demonstrate that they work; see below for why it's done on same frame

ActivateTriggerByName( "TextTrigger" )

ActivateTriggerByName( "AnimTrigger" )

With this method alone, new triggers apparently only exist in the Names table for a very short time, maybe just a few frames or even only one, and the game will crash if you try to activate the trigger in any way after that time. It is not yet known how to make them persist for the entire level. Until we figure that out, one solution to create new "persistent" Triggers might be to have this code running every frame - though you'd have to make it not run while the normal level load/unload stuff is happening. Haven't tested that yet.

Spawning instant one-time Triggers

If you just want to make a new Trigger-like event that instantly happens and then disappears ( instead of being a "normal" Trigger that relies on other Triggers to make it happen and can be reused) you can use the SpawnEvent function from PWeb3.lua. It seems that SpawnEvent is not a global function, so you have to re-define it to use it globally.

SpawnEvent { TriggerType = { var1 = x, var2 = y, var3 = z... basically the same kind of Vars table that would be used with that Trigger type }

Clumps

Clumps are groups of multiple objects, used so that a single Trigger can reference and/or manipulate everything in the Clump at once. All Objects in a clump might need to be the same type of object, like they must be all Triggers, or all Hulls, or all Meshes, etc - not tested yet. Also, a Clump can contain other Clumps.

The functions in this category are from ClumpLoader.lua.

Creating new Clumps

To create new Clumps, define the ClumpInstances table with the same format used in ClumpInstances.lua (but concatenated, not with line breaks). Then run the LoadClumps function, then the SetClumpMembers function. Code "template":

ClumpInstances = { ObjectType = "ClumpInstances", { ObjectName = "NewClumpName", GardenerName = "NewClumpName_G(this name doesn't matter?)", Objects = { "some object's ObjectName", "another object's ObjectName", "and another, etc" } }, { same thing for another new Clump }, {another, etc} }

LoadClumps( game:clumpBarn() )

SetClumpMembers( game:clumpBarn() )

Code example - using this in CS will create a new Clump that duplicates the Clump of Triggers which activates when you stand up after the new-game cutscene:

ClumpInstances = { ObjectType = "ClumpInstances", { ObjectName = "NewGameStandUpEvents", GardenerName = "NewGameStandUpEvents_G", Objects = { "70c1306a4a41c624a9ff123f344ef6ad", "d951daedc9f58a681efd39a8875f32c6", "1a737db99c2f3a7733e5c6426211d0e8", "daa0dd930abe88d5d241e02752c636d4", "f26b85b929a3e48edf43a5ec1f076c91", "65eef6f7bcbfcfa07b32c34d07e53132", "796c354ac61bd62ac987778b9fa96c4c", "5abf9a5b00e2e29c36f7871028e9c1e5", "e4fada7df843f162ebb2ee56a0e9f40f" } } }

LoadClumps( game:clumpBarn() )

SetClumpMembers( game:clumpBarn() )

Demonstration of the new Clump:

SpawnEvent {EventAfterDelay = {delay = 0.01, effects = Names["NewGameStandUpEvents"]}}

Demonstration of the Clump it's duplicating:

SpawnEvent {EventAfterDelay = {delay = 0.01, effects = Names["e7fa07adac45a2fb9a369edcf5964ec7"]}}

Modifying Clumps

To modify existing Clumps, get them from ClumpInstances.lua and do basically the same code, but without the LoadClumps function:

ClumpInstances = { ObjectType = "ClumpInstances", { ObjectName = "original Clump's ObjectName", GardenerName = "original Clump's GardenerName", Objects = { the ObjectNames of whatever objects you want to be in that Clump } }, { same thing for another Clump }, {another, etc} }

SetClumpMembers( game:clumpBarn() )

For example, using this in CS will modify the existing Clump of stand-up-after-new-game Triggers (same as the new Clump example), so that you get knocked over by wind instead of standing up (replacing first Trigger in Objects list) and you hear the music cue from the broken statue symbol cutscene (adding that Trigger at end of list):

ClumpInstances = { ObjectType = "ClumpInstances", { ObjectName = "e7fa07adac45a2fb9a369edcf5964ec7", GardenerName = "|Clump849|Clump849_GARDENER", Objects = { "27b916d7b9ebb26d91432e16257cba5d", "d951daedc9f58a681efd39a8875f32c6", "1a737db99c2f3a7733e5c6426211d0e8", "daa0dd930abe88d5d241e02752c636d4", "f26b85b929a3e48edf43a5ec1f076c91", "65eef6f7bcbfcfa07b32c34d07e53132", "796c354ac61bd62ac987778b9fa96c4c", "5abf9a5b00e2e29c36f7871028e9c1e5", "e4fada7df843f162ebb2ee56a0e9f40f", "ed489eebe96121c9de7ccce1d25d6ced" } } }

SetClumpMembers( game:clumpBarn() )

Demonstration:

SpawnEvent {EventAfterDelay = {delay = 0.01, effects = Names["e7fa07adac45a2fb9a369edcf5964ec7"]}}

Timelines

Timelines are timed sequences of Trigger activations, used to organize cutscenes and other events where a bunch of Triggers get activated in a row.

It has not yet been tested, but Timelines can probably be added and/or modified in a similar way to Triggers and Clumps, based on TimelineInstances.lua's and the functions in TimelineBarn.lua:

TimelineInstances = { construct based on the format in TimelineInstances.lua }

LoadTimelines( game:timelineBarn )

Creatures / Dynamic Nodes

Creatures are dynamically moving and interacting objects, other than the player avatars and the tiny flying cloths (Strands). Although code comments say that Creatures are just a Type of Dynamic Node, it appears that all Dynamic Nodes have their Type set as "Creatures" anyway. Creatures include Fish/Carpets, Guardians/War Machines, Cloth Guardians/Whales/Dragons, Jellyfish, Flow creatures, and Meteors/Comets/Shooting Stars.

It has not yet been tested, but Creatures can probably be added and/or modified in a similar way to Triggers and Clumps, based on DynamicNodeInstances.lua's and the functions in Creatures.lua:

DynamicNodeInstances = { construct based on the format in DynamicNodeInstances.lua }

CreateCreatures( game:creatureBarn() ) --only used when adding new creatures(?)

ResolveCreatureNames( game:creatureBarn() )

It seems that Creatures/Dynamic Nodes might actually be Triggers, based on how TriggerInitialize() is also used in Creatures.lua - so new Creatures might have the same issue as Triggers, and might disappear from the Names table shortly after being created with this method.

Particle Emitters

Particle Emitters emit particles (sparkles, puffs of sand/dust, etc.)

It has not yet been tested, but Particle Emitters can probably be added and/or modified in a similar way to Triggers and Clumps, based on ParticleEmitterInstances.lua's and the functions in EnvFX.lua:

ParticleEmitterInstances = { construct based on the format in ParticleEmitterInstances.lua }

LoadEnvFXParticles( game:envFXBarn(), game:particleBarn() )

Sound Emitters

Sound Emitters emit sounds. They can be stationary or attached to a moving object somehow. It seems that most looping music is played by Sound Emitters that are set to be audible at the same volume anywhere in the level.

It has not yet been tested, but Sound Emitters can probably be added and/or modified in a similar way to Triggers and Clumps, based on SoundEmitterInstances.lua's and the functions in SoundBarn.lua:

SoundEmitterInstances = { construct based on the format in SoundEmitterInstances.lua }

LoadSoundEmitters( game:soundBarn() )

Environment Nodes

Environment/Env Nodes set the environmental effects within certain regions, such as lighting, sky color, shadows, fog, bloom, etc. "IsZNode = true" nodes affect the region all along a certain space on the z-axis (usually toward/away from mountain), "= false" nodes affect a certain cube-shaped volume.

It has not yet been tested, but Env Nodes can probably be added and/or modified in a similar way to Triggers and Clumps, based on EnvNodeInstances.lua's and the functions in Environment.lua:

EnvNodeInstances = { construct based on the format in EnvNodeInstances.lua }

LoadEnvNodes( game:environment() )

There is also an UpdateEnvNamesTableEntry() function in Environment.lua that might be for modifying existing Env Nodes somehow.

LoadEnvNodes does not clear the EnvNodeInstances table automatically upon completion, the code comments say this causes a crash.

Markers

Markers seem to be locations, or regions of space around locations, which objects can be aimed or moved towards/away from by certain Triggers. Also, Markers can be moved around or attached to moving objects by Triggers.

It has not yet been tested, but Markers can probably be added and/or modified in a similar way to Triggers and Clumps, based on MarkerInstances.lua's and the functions in Markers.lua:

MarkerInstances = { construct based on the format in MarkerInstances.lua }

LoadMarkers( game:markerBarn() )

Rails

Rails seem to be paths that objects can move along.

It has not yet been tested, but Rails can probably be added and/or modified in a similar way to Triggers and Clumps, based on RailInstances.lua's and the functions in RailBarn.lua:

RailInstances = { construct based on the format in RailInstances.lua }

LoadRails( railBarn ) ( There doesn't seem to be a game:railBarn(), so maybe it's a different name in game:, or maybe it's used like RailBarn, RailBarn() or RailBarn(game). )

Camera Key Frames

Camera Key Frames seem to be the data for basically any location/angle/etc that the camera can get moved to, whenever the camera moves by itself - not just following behind the player, or being moved around by the player.

It has not yet been tested, but Camera Key Frames can probably be added and/or modified in a similar way to Triggers and Clumps, based on CameraKeyFrameInstances.lua's and the functions in CameraInit.lua:

CameraKeyFrameInstances = { construct based on the format in CameraKeyFrameInstances.lua }

LoadCameraKeyFrames( game:cameraSystem() )

Jets

Jets seem to be the physics effect that pushes your avatar down when you are inside certain sandfalls, and maybe other effects. Could probably be used to push the avatar in other directions as well.

It has not yet been tested, but Jets can probably be added and/or modified in a similar way to Triggers and Clumps, based on JetInstances.lua's and the functions in Jets.lua:

JetInstances = { construct based on the format in JetInstances.lua }

LoadJets( JetBarn ) ( There doesn't seem to be a game:jetBarn(), so maybe it's a different name in game:, or maybe it's used like JetBarn, JetBarn() or JetBarn(game). )

Signs

Signs are scrolling text, used only in the credits. Could maybe be used for other scrolling text as well, although there seem to already be scrolling text Triggers that might be easier for that.

It has not yet been tested, but Signs can probably be added and/or modified in a similar way to Triggers and Clumps, based on SignData.lua's, SignInstances.lua's and the functions in SignBarn.lua:

Credits = { construct based on the format in SignData.lua }

SignInstances = { construct based on the format in SignInstances.lua }

InitializeSignBarn( signBarn, signData, signInstances ) ( There doesn't seem to be a game:signBarn(), so maybe it's a different name in game:, or maybe it's used like SignBarn, SignBarn() or SignBarn(game). Also, signData/signInstances don't seem to actually be referenced inside InitializeSignBarn, so they might not be required, but if required then maybe signData is Credits and signInstances is SignInstances. )