### Create and Organize Spells and Components in Lua Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This snippet demonstrates how to create spell cards, define pattern components with specific behaviors like spawning and movement, and group them for stage organization. It also shows how to create multiple spells for stage structure and export all components to a JSON file. It relies on local libraries for spells, components, and utilities. ```lua local lib = require("lib") local comp = require("component") local util = require("utils") -- Create a spell card local spell = lib.Spell.new("Frozen Sign: Diamond Dust", util.group(1000)) -- Create pattern components local radialPattern = comp.Component.new("DiamondRadial", util.unknown_g(), 4) radialPattern:assertSpawnOrder(true) :GotoGroup(0, enum.EMPTY_BULLET, 30, { t = 0 }) :Toggle(enum.TICK, enum.EMPTY_BULLET, true) :MoveTowards(0, enum.EMPTY_BULLET, enum.PLR, { t = 3, type = enum.Easing.LINEAR, rate = 1, dist = 400 }) -- Add components to spell spell:AddComponent(radialPattern) -- Create multiple spells for stage structure local stage1Boss = lib.Spell.new("CirnoNonSpell1", util.group(1100)) local stage1Spell1 = lib.Spell.new("Ice Sign: Icicle Fall", util.group(1200)) local stage1Spell2 = lib.Spell.new("Frozen Sign: Perfect Freeze", util.group(1300)) -- Export all components to triggers.json lib.SaveAll(comp.GetAllComponents()) ``` -------------------------------- ### Lua: Multitarget Registry for Mass Spawning Source: https://context7.com/extremekiller145/touhou-scs/llms.txt Illustrates the use of the multitarget registry in Lua for optimizing the spawning of multiple bullets through binary decomposition in Touhou SCS. It requires 'lib', 'component', and 'enums' libraries. The registry is auto-initialized. ```lua local lib = require("lib") local comp = require("component") local enum = require("enums") -- Registry is auto-initialized when component.lua loads -- Supports 1-127 simultaneous spawns efficiently -- Get binary components for 47 bullets (32 + 8 + 4 + 2 + 1) local components = lib.MultitargetRegistry:getBinaryComponents(47) print("Spawning 47 bullets requires " .. #components .. " spawn triggers") -- Components automatically decompose into powers of 2 -- Each component has pre-built spawn chains for _, binaryComp in ipairs(components) do print("Component: " .. binaryComp.componentName) print("Triggers: " .. #binaryComp.triggers) end -- Manual usage (normally handled by instant_Radial/Arc) local bulletType = lib.Bullet.Bullet1 local remapString = "" for _, binComp in ipairs(components) do for _, trigger in ipairs(binComp.triggers) do local pairs = util.translateRemapString(trigger[enum.Properties.REMAP_STRING]) for source, target in pairs(pairs) do -- Replace empty placeholders with actual groups if tonumber(source) == enum.EMPTY_BULLET then remapString = remapString .. target .. "." .. bulletType.nextBullet() .. "." end end end end ``` -------------------------------- ### Component Creation and Trigger Management in Lua Source: https://context7.com/extremekiller145/touhou-scs/llms.txt Demonstrates how to create and manage components, which are the fundamental building blocks for bullet patterns and behaviors in the Touhou Shattered Crystal Shards project. This Lua code shows chaining trigger methods to define a bullet's lifecycle from creation to movement and visual effects. ```lua local comp = require("component") local enum = require("enums") local util = require("utils") -- Create a new component with a unique caller group and editor layer local bulletComponent = comp.Component.new("MyBulletPattern", util.unknown_g(), 4) -- Assert spawn order requirement (true = sequential, false = simultaneous, nil = either) bulletComponent:assertSpawnOrder(true) -- Build a complete bullet lifecycle with chained trigger methods bulletComponent -- Move bullet to emitter position instantly :GotoGroup(0, enum.EMPTY_BULLET, 30, { t = 0 }) -- Scale up the bullet :Scale(0, enum.EMPTY_BULLET, 2, { t = 0 }) -- Activate the bullet after one tick :Toggle(enum.TICK, enum.EMPTY_BULLET, true) -- Fade in with alpha animation :Alpha(0, enum.EMPTY_BULLET, { t = 0, opacity = 0}) :Alpha(enum.TICK, enum.EMPTY_BULLET, { t = 1, opacity = 1.00}) -- Point bullet toward target :PointToGroup(enum.TICK, enum.EMPTY_BULLET, enum.EMPTY_TARGET_GROUP) -- Move bullet toward target with easing :MoveTowards(0.3, enum.EMPTY_BULLET, enum.EMPTY_TARGET_GROUP, { t = 1.8, type = enum.Easing.EASE_IN_OUT, rate = 2.01, dist = 70 }) -- Add color pulse effect :Pulse(2.1, enum.EMPTY_BULLET, {h = 54, s = 124, b = 156, exclusive = false}, { fadeIn = 0.1, t = 0.1, fadeOut = 0.3 }) -- Access all component triggers print("Component has " .. #bulletComponent.triggers .. " triggers") ``` -------------------------------- ### Activate Spawn Triggers with Group Remapping (Lua) Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This snippet demonstrates how to use spawn triggers with group remapping to dynamically assign bullet visuals and targets. It shows how to create remap strings using a builder utility and then use these strings to spawn components with remapped groups, including ordered spawns and complex multitarget patterns. Dependencies include 'component', 'enums', and 'utils' libraries. ```lua local comp = require("component") local enum = require("enums") local util = require("utils") -- Create remap strings using the builder utility local remapBuilder = util.remap() remapBuilder :pair(enum.EMPTY_BULLET, 550) -- Remap bullet placeholder to group 550 :pair(enum.EMPTY_TARGET_GROUP, 200) -- Remap target placeholder to group 200 :pair(21, 6001) -- Remap additional empty group local remapString = remapBuilder:toString() -- "10.550.20.200.21.6001" -- Spawn component with remapping local spawner = comp.Component.new("Spawner", util.group(40), 4) spawner:Spawn(0, 100, false, remapString, 0) -- Spawn ordered (executes spawns sequentially with delay) spawner:Spawn(1.0, 200, true, "10.600.20.300", 0.1) -- Complex multitarget spawn pattern local bulletType = lib.Bullet.Bullet2 for i = 1, 8 do local remap = util.remap() remap:pair(enum.EMPTY_BULLET, bulletType.nextBullet()) :pair(enum.EMPTY_TARGET_GROUP, 100 + i) :pair(enum.EMPTY_MULTITARGET, 999) spawner:Spawn(i * 0.2, 150, false, remap:toString()) end ``` -------------------------------- ### Control Object Movement and Transforms (Lua) Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This snippet illustrates how to control object movement using various triggers. It covers moving by relative offsets with easing, moving towards a target group, teleporting, rotating, pointing towards a target, and scaling objects. Dependencies include 'component', 'enums', and 'utils' libraries. ```lua local comp = require("component") local enum = require("enums") local util = require("utils") local moveComponent = comp.Component.new("MovementDemo", util.unknown_g(), 4) -- Move by relative offset with easing moveComponent:MoveBy(0, 100, util.vector2(150, -50), { t = 2.0, type = enum.Easing.EASE_OUT, rate = 2 }) -- Move towards another group with distance and direction moveComponent:MoveTowards(2.0, 100, 200, { t = 3.0, type = enum.Easing.SINE_IN_OUT, rate = 1, dist = 300, dynamic = true }) -- Teleport to another group's location moveComponent:GotoGroup(5.0, 100, 200, { t = 1.5, type = enum.Easing.BOUNCE_OUT, rate = 1 }) -- Rotate around a center point moveComponent:Rotate(0, { target = 100, center = 200 }, { angle = 90, t = 2.0, type = enum.Easing.BACK_IN_OUT, rate = 1.5 }) -- Point object toward target group moveComponent:PointToGroup(1.0, 100, enum.PLR, { t = 0.5, dynamic = true, rate = 50 }) -- Scale object up or down moveComponent:Scale(0, 100, 1.5, { t = 1.0, type = enum.Easing.ELASTIC_OUT, rate = 2 }, false) -- Scale down by dividing (divideMode = true) moveComponent:Scale(2.0, 100, 2, { t = 0.5, type = enum.Easing.EASE_IN, rate = 1 }, true) -- Follow another group's movement moveComponent:Follow(3.0, 100, enum.PLR, 5.0) ``` -------------------------------- ### Utilize Utility Functions for Groups, Timing, and Vectors in Lua Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This code snippet showcases various utility functions for managing game logic. It covers creating and validating groups, performing time and distance conversions, calculating bullet spacing, creating Vector2 objects for movement, and using number and bullet cyclers for allocation and group generation. It depends on 'utils' and 'enums' libraries. ```lua local util = require("utils") local enum = require("enums") -- Create unknown groups (auto-assigned IDs, remapped at export) local group1 = util.unknown_g() -- Returns "unknown_g1" local group2 = util.unknown_g() -- Returns "unknown_g2" -- Explicit group assignment with validation local playerGroup = util.group(2) local emitterGroup = util.group(30) -- Validate groups (checks restricted groups and valid ranges) util.validateGroups("MyFunction", playerGroup, emitterGroup) -- Time and distance conversions (311.58 studs/second) local distance = util.timeToDist(5.0) -- 5 seconds = 1557.9 studs local time = util.distToTime(1000) -- 1000 studs = 3.21 seconds -- Calculate bullet spacing for time-based patterns local bulletSpeed = 200 -- studs/second local spacing = 50 -- studs between bullets local timeSpacing = util.spacingBullet(bulletSpeed, spacing) -- 77.895 time units -- Vector2 for MoveBy operations local offset = util.vector2(100, -75) local moveVector = util.vector2(-200.5, 150.25) -- Number cyclers for group allocation local groupCycler = util.createNumberCycler(5000, 5100) for i = 1, 10 do print("Group: " .. groupCycler()) -- 5000, 5001, 5002... end -- Bullet cyclers return bullet and collision groups local bulletCycler = util.createBulletCycler(501, 600) local bulletGroup, collisionGroup = bulletCycler() print("Bullet: " .. bulletGroup .. ", Collision: " .. collisionGroup) -- Parse remap strings into key-value pairs local pairs = util.translateRemapString("10.550.20.200.21.6001") -- Returns: { ["10"] = "550", ["20"] = "200", ["21"] = "6001" } ``` -------------------------------- ### Lua: Visual Effects (Alpha, Pulse, Stop, Pause, Resume, Toggle) Source: https://context7.com/extremekiller145/touhou-scs/llms.txt Demonstrates how to control visual effects such as fading (Alpha), color pulsing (Pulse), stopping, pausing, resuming, and toggling component visibility using Lua in Touhou SCS. It utilizes the 'component' and 'enums' libraries for effect management. ```lua local comp = require("component") local enum = require("enums") local vfxComponent = comp.Component.new("VisualEffects", util.group(75), 4) -- Fade in effect vfxComponent:Alpha(0, 100, { opacity = 0, t = 0 }) vfxComponent:Alpha(0.1, 100, { opacity = 1.0, t = 0.5 }) -- Fade out effect vfxComponent:Alpha(3.0, 100, { opacity = 0.3, t = 1.0 }) -- Color pulse with HSB values -- Hue: -180 to +180, Saturation: 0-200 (x2.0), Brightness: 0-255 (x2.0) vfxComponent:Pulse(1.0, 100, { h = 120, s = 150, b = 200, exclusive = true }, { fadeIn = 0.2, t = 0.5, fadeOut = 0.3 }) -- Multiple pulses for layered effects vfxComponent:Pulse(0, 200, { h = -64, s = 124, b = 255, exclusive = false }, { fadeIn = 0, t = 10, fadeOut = 0 }) -- Stop triggers (stops Move, Rotate, Follow, Pulse, Alpha, Scale, Spawn) vfxComponent:Stop(5.0, 100, false) -- Pause triggers (can be resumed later) vfxComponent:Pause(2.0, 150, false) -- Resume paused triggers vfxComponent:Resume(4.0, 150, false) -- Toggle group activation/deactivation vfxComponent:Toggle(0, 100, true) -- Activate vfxComponent:Toggle(10.0, 100, false) -- Deactivate ``` -------------------------------- ### Export Components to Geometry Dash Triggers using Lua Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This code demonstrates the process of exporting created components into Geometry Dash trigger format. It involves retrieving all registered components and using a save function to write them to a 'triggers.json' file. The export process includes spatial distribution, validation of group IDs, ensuring positional differences, generating budget statistics, and mapping trigger properties. ```lua local lib = require("lib") local comp = require("component") -- Create all your components and patterns local component1 = comp.Component.new("Pattern1", util.group(100), 4) -- ... add triggers to components ... -- Get all registered components local allComponents = comp.GetAllComponents() -- Export to triggers.json for G.js consumption lib.SaveAll(allComponents) ``` -------------------------------- ### Lua: Collision Detection and Player Interaction Source: https://context7.com/extremekiller145/touhou-scs/llms.txt Shows how to implement collision detection for bullet-player and bullet-boundary interactions using Lua in Touhou SCS. It covers adding player collisions, disabling bullets, and custom despawn logic. Relies on 'misc', 'component', 'enums', and 'utils' libraries. ```lua local misc = require("misc") local comp = require("component") local enum = require("enums") local util = require("utils") -- Add collision detection for all bullet types (automatically generates triggers) misc.addPlayerCollision() -- Add bullet disable functionality for game start/reset misc.addDisableAllBullets() -- Custom collision component example local despawnFunction = comp.Component.new("CustomDespawn", util.unknown_g(), 4) despawnFunction:assertSpawnOrder(true) :Scale(0, enum.EMPTY1, 0.5, { t = 0.3 }) :Alpha(0, enum.EMPTY1, { t = 0.3, opacity = 0 }) :Toggle(0.3, enum.EMPTY1, false) -- Collision triggers are automatically inserted by misc.addPlayerCollision() -- They handle: -- - Boundary collision (block_b = 1) - despawn bullets leaving screen -- - Player collision (block_b = enum.PLR) - despawn and trigger damage -- - Graze detection (block_b = 3) - score increment without despawn -- Access collision groups: each bullet gets collision group = bulletGroup + maxBullet -- Example: Bullet1 group 550 gets collision group 550 + 500 = 1050 ``` -------------------------------- ### Manage Bullet Types and Group Allocation (Lua) Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This snippet demonstrates how to manage bullet types, access predefined types with automatic group cycling, and create custom bullet types with specific group ranges. It also shows how to use these bullet types within component patterns. ```lua local lib = require("lib") local util = require("utils") -- Access predefined bullet types with automatic group cycling local bullet1 = lib.Bullet.Bullet1 -- Groups 501-1000 local bullet2 = lib.Bullet.Bullet2 -- Groups 1501-2200 local bullet3 = lib.Bullet.Bullet3 -- Groups 2901-3600 local bullet4 = lib.Bullet.Bullet4 -- Groups 4301-4700 -- Get next available bullet group (cycles through range) local bulletGroup = bullet1.nextBullet() print("Spawned bullet in group: " .. bulletGroup) -- Create custom bullet type with specific group range local customBullet = { minGroup = 7001, maxGroup = 7500, nextBullet = util.createBulletCycler(7001, 7500) } -- Use bullet types in patterns local component = comp.Component.new("Test", util.unknown_g(), 4) component:assertSpawnOrder(true) :GotoGroup(0, enum.EMPTY_BULLET, 30, { t = 0 }) :Toggle(0.1, enum.EMPTY_BULLET, true) local caller = comp.Component.new("Caller", util.group(50), 4) caller:instant_Radial(0, component, lib.GuiderCircles.circle1, bullet3, { numOfBullets = 36, centerAt = 0 }) ``` -------------------------------- ### Radial and Arc Bullet Patterns in Lua Source: https://context7.com/extremekiller145/touhou-scs/llms.txt Shows how to implement radial and arc bullet patterns using pre-configured guider circles and component-based lifecycles in Lua. This code defines bullet behaviors and uses caller components to spawn patterns like full circles, arcs, and timed radial waves. ```lua local lib = require("lib") local comp = require("component") local util = require("utils") -- Get a pre-configured guider circle with 360 degree markers local circle = lib.GuiderCircles.circle1 -- Create bullet lifecycle component (must use spawn ordering) local bulletBehavior = comp.Component.new("RadialBullet", util.unknown_g(), 4) bulletBehavior:assertSpawnOrder(true) :GotoGroup(0, enum.EMPTY_BULLET, 30, { t = 0 }) :Toggle(enum.TICK, enum.EMPTY_BULLET, true) :MoveTowards(0, enum.EMPTY_BULLET, enum.EMPTY_TARGET_GROUP, { t = 2.0, type = enum.Easing.LINEAR, rate = 1, dist = 400 }) -- Create caller component to spawn the pattern local caller = comp.Component.new("PatternCaller", util.group(36), 4) -- Spawn a full 360-degree radial with 72 bullets (5 degree spacing) caller:instant_Radial(0, bulletBehavior, circle, lib.Bullet.Bullet1, { spacing = 5, centerAt = 0 }) -- Spawn an arc pattern with 10 bullets at 14 degree spacing centered at 45 degrees caller:instant_Arc(1.5, bulletBehavior, circle, lib.Bullet.Bullet2, { numOfBullets = 10, spacing = 14, centerAt = 45 }) -- Create a radial wave pattern with multiple waves over time caller:timed_RadialWave(3.0, bulletBehavior, circle, lib.Bullet.Bullet3, { numOfBullets = 24, waves = 10, interval = 0.3, centerAt = 0 }) ``` -------------------------------- ### JavaScript: Load, Process, and Export Geometry Dash Triggers Source: https://context7.com/extremekiller145/touhou-scs/llms.txt This script loads trigger data from a JSON file, resolves and maps 'unknown_g' identifiers to actual group IDs using a dictionary, replaces these references in trigger properties (like 'GROUPS' and 'REMAP_STRING'), and finally adds the processed triggers to Geometry Dash using the GJS API. It relies on external libraries like '@g-js-api/g.js' and Node.js's 'fs' module. ```javascript // main.js - Load and process generated triggers require('@g-js-api/g.js'); $.exportConfig({ type: 'live_editor', options: { info: true, level_name: "touhou scs mig" } }).then(() => { const jsonData = require('fs').readFileSync('triggers.json', 'utf8'); const data = JSON.parse(jsonData); // Registry maps unknown_g1, unknown_g2... to actual unknown_g() results const unknownG_dict = {}; // Scan all triggers and register unknown groups data.triggers.forEach(trigger => { Object.values(trigger).forEach(value => { if (typeof value === 'string' && value.match(/^unknown_g\d+$/)) { if (!unknownG_dict[value]) { unknownG_dict[value] = unknown_g(); } } // Also handle remap strings containing unknown groups if (typeof value === 'string' && value.includes('unknown_g')) { const matches = value.match(/unknown_g\d+/g); matches?.forEach(match => { if (!unknownG_dict[match]) { unknownG_dict[match] = unknown_g(); } }); } }); }); // Replace all unknown group references with actual groups const triggers = data.triggers.map(trigger => { return Object.keys(trigger).reduce((acc, key) => { if (key === '57') { // GROUPS property const groupData = Array.isArray(trigger[key]) ? trigger[key] : [trigger[key]]; acc['GROUPS'] = groupData.map(val => unknownG_dict[val] ? unknownG_dict[val] : group(val) ); } else if (key === '442') { // REMAP_STRING let str = trigger[key]; Object.keys(unknownG_dict).forEach(unknownKey => { str = str.replace(new RegExp(unknownKey, 'g'), unknownG_dict[unknownKey].value); }); acc[key] = str; } else { acc[key] = trigger[key]; } return acc; }, {}); }); triggers.forEach(trigger => $.add(object(trigger))); console.log(`Processed ${triggers.length} triggers`); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.