# PSXSplash Test Scene - Unity Setup Guide This test scene exercises every Lua API namespace and callback. Follow these steps to set it up in SplashEdit. ## Prerequisites - Unity project with SplashEdit (the `splashedit` package) - A font atlas configured (for UI text) - Audio clips imported (or skip audio-related tests) ## Step 1: Create the Scene 1. Create a new Unity scene 2. Add a **PSXSceneExporter** component to a root GameObject 3. Add a **PSXPlayer** prefab (for player movement, gravity, collision) 4. Add **PSXNavRegion** components to define walkable floor areas ## Step 2: Create Lua Files Create **LuaFile** ScriptableObjects (Assets > Create > PSXSplash > Lua File) for each script: | Lua File Name | Script | |---------------|--------| | `scene` | `scene.lua` (attach to scene, not an object) | | `collectible` | `collectible.lua` | | `door` | `door.lua` | | `npc` | `npc.lua` | | `switch` | `switch.lua` | | `spinner` | `spinner.lua` | | `movable` | `movable.lua` | | `entity_scanner` | `entity_scanner.lua` | Paste each `.lua` file's content into the corresponding LuaFile asset's text field. ## Step 3: Set Up Scene Script On the PSXSceneExporter, assign the `scene` LuaFile to the **Scene Script** field. This handles `onSceneCreationStart`, `onSceneCreationEnd`, and `onTriggerEnter/Exit`. ## Step 4: Create Game Objects For each entity script, create a GameObject in the scene: ### Collectibles (x3) - Create 3 GameObjects with mesh renderers (cubes, spheres, etc.) - Add **PSXObjectExporter** to each, assign the `collectible` LuaFile - Space them around the scene so the player can walk into them - They use `onCollideWithPlayer` - no PSXInteractable needed ### NPC - Create a GameObject with a character mesh - Add **PSXObjectExporter**, assign `npc` LuaFile - Add **PSXInteractable** component (so `onInteract` fires when player presses Cross nearby) ### Door - Create a door mesh GameObject - Add **PSXObjectExporter**, assign `door` LuaFile - Add **PSXInteractable** component - Create a second GameObject named exactly **"DoorBlocker"** (invisible wall blocking the doorway) - Add **PSXObjectExporter** to DoorBlocker (no script needed) - The door script finds it by name and hides it when opened ### Switch - Create a switch/lever mesh GameObject - Add **PSXObjectExporter**, assign `switch` LuaFile - Add **PSXInteractable** component - Create a second GameObject named exactly **"SwitchTarget"** - Add **PSXObjectExporter** (no script needed) - The switch toggles this object's active state ### Spinner - Create a decorative mesh (pillar, gem, etc.) - Add **PSXObjectExporter**, assign `spinner` LuaFile - Add **PSXInteractable** component (so player can start/stop the spin) ### Movable - Create a box/crate mesh - Add **PSXObjectExporter**, assign `movable` LuaFile - Add **PSXInteractable** component (interact to select, then D-pad to move) ### Entity Scanner - Create a terminal/pedestal mesh - Add **PSXObjectExporter**, assign `entity_scanner` LuaFile - Add **PSXInteractable** component ## Step 5: Create Trigger Boxes Add **PSXTriggerBox** components to empty GameObjects. The scene script handles these by index: | Trigger Index | Purpose | Placement | |---------------|---------|-----------| | 0 | Cutscene zone | Near a scenic viewpoint | | 1 | Damage zone | In a hazard area (lava, spikes, etc.) | | 2 | Scene transition portal | At a doorway/exit | | 3 | Heal zone | Near a health pickup area | Trigger indices are assigned in the order they appear in the scene hierarchy. ## Step 6: Create UI Canvases In the SplashEdit UI editor, create two canvases: ### Canvas: "HUD" | Element Name | Type | Purpose | |-------------|------|---------| | ScoreText | Text | Shows "Score: 0" | | StatusText | Text | Shows status messages | | HealthBar | Progress | Shows health 0-100 | ### Canvas: "Dialogue" | Element Name | Type | Purpose | |-------------|------|---------| | DialogueText | Text | Shows NPC dialogue lines | Set the Dialogue canvas to **initially hidden**. ## Step 7: Create Cutscenes Create **PSXCutsceneClip** assets for: | Cutscene Name | Type | Description | |---------------|------|-------------| | `ambient_spin` | Looping | Background ambient animation (object rotation, etc.) | | `camera_flyover` | One-shot | Camera pan across the scene (Camera Position + Rotation tracks) | | `door_open` | One-shot | Door opening animation (Object Position track) | | `spin_loop` | Looping | Full 360-degree rotation for the spinner object (Object Rotation track) | ## Step 8: Audio Clips Import or create placeholder audio clips named: - `collect` - pickup sound - `door_open` - door opening - `switch_on` / `switch_off` - switch toggle sounds - `heal` - healing sound ## Step 9: Build and Test 1. Open Splash Control Panel (Window > PSXSplash > Control Panel) 2. Click **Build and Run** 3. Watch the PSX Console for Debug.Log output from all scripts 4. Walk around and interact with objects to test each callback ## What Each Script Tests | Script | Callbacks | API Namespaces | |--------|-----------|----------------| | scene.lua | onSceneCreationStart, onSceneCreationEnd, onTriggerEnter, onTriggerExit | Scene, Persist, UI, Audio, Controls, Cutscene, Timer, Debug, PSXMath, Vec3 | | collectible.lua | onCreate, onDestroy, onEnable, onDisable, onCollideWithPlayer | Entity, Audio, Persist | | door.lua | onCreate, onInteract | Entity, Audio, Controls, Cutscene | | npc.lua | onCreate, onInteract, onButtonPress | Input, Controls, UI | | switch.lua | onCreate, onInteract | Entity, Audio | | spinner.lua | onCreate, onInteract, onCollideWithPlayer | Cutscene, Entity, Timer | | movable.lua | onCreate, onInteract, onButtonPress | Entity, Vec3, Camera, Input | | entity_scanner.lua | onInteract | Entity, Vec3 | ## Key Design Notes - **No onUpdate anywhere.** All logic is event-driven. Rotation uses a looping cutscene. - **No float literals.** PS1 Lua uses integer-only numbers. Use `1/2` instead of `0.5`, `1/4` instead of `0.25`, etc. - **Scene globals.** `scene.lua` defines `addScore()`, `setStatus()`, `startDialogue()`, `advanceDialogue()`, `isInDialogue()`, `endDialogue()` as globals. Other scripts call these directly.