the cutting room mirror

Mark of the Ninja

This page contains no introduction.
What makes this game notable or what is it about? Are you a bad enough dude to save this article?

Debug Scripts#

autoexec.lua#

--Print("loading autoexec.lua foobar")
PAUSE_SIMULATION = "PAUSE/UNPAUSE SIMULATION"
WIN_LEVEL = "WIN LEVEL"
GOD_MODE = "GOD MODE (Ctrl+G)"
INVISIBILITY = "INVISIBILITY (Ctrl+I)"
SUPER_SPEED = "SUPER SPEED MODE"
RELOAD_LEVEL = "RELOAD LEVEL"
CHECKPOINT_TELEPORT = "TELEPORT TO CHECKPOINT (Ctrl+T)"
REFILL_AMMO = "REFILL AMMO (Ctrl+A)"
UNLOCK_ALL = "UNLOCK ALL"
UNLOCK_SHOP = "UNLOCK SHOP"
ADD_HONOUR = "ADD HONOUR"
RESET_UNLOCKS = "RESET UNLOCKS"
CREATE_SOUND = "CREATE SOUND"
HIDE_HUD = "HIDE HUD"
REVEAL_MAP = "REVEAL MAP"
SHOW_LOADOUT = "LOADOUT SCREEN"
TOGGLE_PATHING = "TOGGLE PATH DBG (Ctrl+P)"
TOGGLE_PHYSICS = "TOGGLE PHYSICS DBG (Ctrl+O)"
TOGGLE_LIGHTING = "TOGGLE LIGHTING DBG"
TOGGLE_FOW = "TOGGLE FOW DBG"
TOGGLE_SOUND = "TOGGLE SOUND DBG"
TOGGLE_TRIGGER = "TOGGLE TRIGGER DBG"
TOGGLE_CAMERA = "TOGGLE CAMERA DBG"
PROFILE_TESTS = "Profile Tests"
PROFILE_COLLISION = "Profile Collision"
HELP_MENU = "DEBUG KEY HELP"
CHECKPOINT_SWITCH = "SWITCH CHECKPOINT"
SELECTION_GUARDS = "Guards"
SELECTION_PROPS = "Props"
SELECTION_LIGHTS = "Lights"
SELECTION_DOORS = "Doors"
SELECTION_HIDINGSPOTS = "Hiding Spots"
SELECTION_OTHER = "Other"
SELECTION_BACK = "Back"
SELECTION_PAGE_NEXT = "Next Page"
SELECTION_PAGE_PREV = "Previous Page"
MAIN_MENU = "Main"

ACTION_FORWARD = 1
ACTION_BACK = -1

ITEMS_PER_PAGE = 28

-- Look here for the list of spawnable objects:
LoadFile("gameobjectlist.lua")

mainMenuList = 
{
    "== Helper Functions ==",
    GOD_MODE,
    INVISIBILITY,
    CHECKPOINT_SWITCH,
    CHECKPOINT_TELEPORT,
    SHOW_LOADOUT,
    REFILL_AMMO,
    ADD_HONOUR,
    UNLOCK_ALL,
    UNLOCK_SHOP,
    RESET_UNLOCKS,
    HIDE_HUD,
    REVEAL_MAP,
    SUPER_SPEED,
    PAUSE_SIMULATION,
    WIN_LEVEL,
    "== Debugging ==",
    TOGGLE_PATHING,
    TOGGLE_PHYSICS,
    TOGGLE_LIGHTING,
    TOGGLE_FOW,
    TOGGLE_SOUND,
    TOGGLE_TRIGGER,
    TOGGLE_CAMERA,
    PROFILE_TESTS,
    HELP_MENU,
    "== Game Objects ==",
    SELECTION_PROPS,
    SELECTION_GUARDS,
}

helpList = 
{
    "== Utility ==",
    "X -- Teleport Ninja",
    "C -- Reload current cameras",
    "H -- Toggle HUD",
    "Numpad -- Adjust current camera",
    "CTRL+A -- Refill Ninja Items",
    "CTRL+R -- Reload level",
    "CTRL+SHIFT+R -- Reload level at last checkpoint",
    "CTRL+Y -- Create Sound interest",
    "1-9/SHIFT+1-9 -- Select checkpoint",
    "== Debugging ==",
    "BREAK -- pause game",
    "PGUP/PGDOWN -- rewind / go forward while paused",
    "T -- Toggle debug text",
    "Backspace -- Toggle Debug Rendering",
    "F2 -- Toggle Stategraph debug spew",
    "CTRL+L -- Go to currently debugged stategraph",
    "========",
}

propsList = 
{
    SELECTION_LIGHTS,
    SELECTION_DOORS,
    SELECTION_HIDINGSPOTS,
    SELECTION_OTHER,
    
    SELECTION_BACK,
}

table.insert(guards, SELECTION_BACK)
table.insert(lights, SELECTION_BACK)
table.insert(doors, SELECTION_BACK)
table.insert(hidingspots, SELECTION_BACK)
table.insert(other, SELECTION_BACK)

menuList =
{
    [MAIN_MENU] =
    {
        items = mainMenuList,
        prevMenu = nil,
        selectedIndex = 1,
        startIndex = 1,
    },

    [SELECTION_GUARDS] =
    {
        items = guards,
        prevMenu = MAIN_MENU,
        selectedIndex = 1,
        startIndex = 1,
    },
    [SELECTION_PROPS] =
    {
        items = propsList,
        prevMenu = MAIN_MENU,
        selectedIndex = 1,
        startIndex = 1,
    },
    [SELECTION_LIGHTS] =
    {
        items = lights,
        prevMenu = SELECTION_PROPS,
        selectedIndex = 1,
        startIndex = 1,
    },
    [SELECTION_DOORS] =
    {
        items = doors,
        prevMenu = SELECTION_PROPS,
        selectedIndex = 1,
        startIndex = 1,
    },
    [SELECTION_HIDINGSPOTS] =
    {
        items = hidingspots,
        prevMenu = SELECTION_PROPS,
        selectedIndex = 1,
        startIndex = 1,
    },
    [SELECTION_OTHER] =
    {
        items = other,
        prevMenu = SELECTION_PROPS,
        selectedIndex = 1,
        startIndex = 1,
    },
    [PROFILE_TESTS] =
    {
        items =
        {
            PROFILE_COLLISION,
            SELECTION_BACK,
        },
        prevMenu = MAIN_MENU,
        selectedIndex = 1,
        startIndex = 1,
    },
    [HELP_MENU] =
    {
        items = helpList,
        prevMenu = MAIN_MENU,
        selectedIndex = 1,
        startIndex = 1,
    },
}

currentMenu = menuList[MAIN_MENU]

function CheckMenuOverflow()
    --DebugTable.DebugString = DebugTable.DebugString.."items: ".. table.getn(currentMenu.items).."\n"
    if (table.getn(currentMenu.items) > ITEMS_PER_PAGE) then
        if (currentMenu.selectedIndex > currentMenu.startIndex + ITEMS_PER_PAGE) then
            currentMenu.startIndex = currentMenu.startIndex + 1
        elseif (currentMenu.selectedIndex < currentMenu.startIndex) then
            currentMenu.startIndex = currentMenu.startIndex - 1
        end
    end
end

function CheckMenuWrapAround()
    if currentMenu.selectedIndex > table.getn(currentMenu.items) then
        currentMenu.selectedIndex = 1
        currentMenu.startIndex = 1
    elseif currentMenu.selectedIndex <= 0 then
        currentMenu.selectedIndex = table.getn(currentMenu.items)
        if (table.getn(currentMenu.items) > ITEMS_PER_PAGE) then
            currentMenu.startIndex = table.getn(currentMenu.items) - ITEMS_PER_PAGE
        end
    end
end

function GenerateSplitMenu(menu, page)
    local splitMenu = {}
    -- There are less menu items in this list, so return everything
    if table.getn(menu) <= ITEMS_PER_PAGE then
        return menu
    else
        -- Depending on the page number, determine the start and end menu elements of the table
        local startIndex = page * ITEMS_PER_PAGE + 1

        for i = startIndex, startIndex + ITEMS_PER_PAGE - 1, 1 do
            if i > table.getn(menu) then
                break
            end
            Print(i.." " .. menu[i])
            table.insert(splitMenu, menu[i])
        end
        
        -- Add either next or previous page options, or both
        if (page * ITEMS_PER_PAGE + ITEMS_PER_PAGE < table.getn(menu)) then
            table.insert(splitMenu, SELECTION_PAGE_NEXT)
        end
        if (page > 0) then
            table.insert(splitMenu, SELECTION_PAGE_PREV)
        end
    end
    return splitMenu
end

function UpdateDebugString(indexMove)

    currentMenu.selectedIndex = currentMenu.selectedIndex + indexMove
    CheckMenuOverflow()
    CheckMenuWrapAround()
    local checkpointName = GetCurrentCheckpointName( pSimulation )
    
    local menuToDisplay = currentMenu.items
    --local menuToDisplay = GenerateSplitMenu(currentMenu.items, pageNum)

    -- Ignore menu titles
    if (string.find(menuToDisplay[currentMenu.selectedIndex], "==") ~= nil) then
        repeat
            if (indexMove < 0) then
                currentMenu.selectedIndex = currentMenu.selectedIndex - 1
            else
                currentMenu.selectedIndex = currentMenu.selectedIndex + 1
            end

            CheckMenuWrapAround()
        until (currentMenu.selectedIndex > table.getn(menuToDisplay) or currentMenu.selectedIndex <= 0 or (string.find(menuToDisplay[currentMenu.selectedIndex], "==") == nil))
    end
    
    -- TODO: Add support for recently spawned game objects & multiple page support for lists:
    
    local rows = table.getn(menuToDisplay) + 4
    DebugTable.DebugString = "CURRENT CHECKPOINT: "..checkpointName.."\nUse dPad up/down to Navigate\ndPad right to select\ndPad left to go back\n----------------\n"

    for i=currentMenu.startIndex, currentMenu.startIndex + ITEMS_PER_PAGE do
        if menuToDisplay[i] == nil then
            break
        end
        
        if i == currentMenu.selectedIndex then
            DebugTable.DebugString = DebugTable.DebugString.."> "..menuToDisplay[i].." <\n"
        elseif (string.find(menuToDisplay[i], "==") ~= nil) then
            DebugTable.DebugString = DebugTable.DebugString..menuToDisplay[i].."\n"
        else
            DebugTable.DebugString = DebugTable.DebugString.."  "..menuToDisplay[i].."\n"
        end
    end
    
    if (currentMenu.startIndex + ITEMS_PER_PAGE < table.getn(menuToDisplay)) then
        DebugTable.DebugString = DebugTable.DebugString.."  ...\n"
    end

    SingleStep()
end

function MenuBackAction()
    if (currentMenu.prevMenu ~= nil) then
        currentMenu = menuList[currentMenu.prevMenu]
        currentMenu.selectedIndex = currentMenu.selectedIndex
        UpdateDebugString(0)
    end
end

function DebugAction(action)

    if currentMenu.items[currentMenu.selectedIndex] == GOD_MODE then
        ToggleGodMode( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == PAUSE_SIMULATION then
        TogglePause( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == WIN_LEVEL then
        SetGameOver( pSimulation, 3 )
    elseif currentMenu.items[currentMenu.selectedIndex] == INVISIBILITY then
        ToggleInvisibility( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == SUPER_SPEED then
        ToggleSuperSpeed( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == REFILL_AMMO then
        RefillAmmo( pPlayer1 )
    elseif currentMenu.items[currentMenu.selectedIndex] == UNLOCK_ALL then
        UnlockAll( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == UNLOCK_SHOP then
        UnlockShop( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == ADD_HONOUR then
        AddHonour( pSimulation, 10 )
    elseif currentMenu.items[currentMenu.selectedIndex] == RESET_UNLOCKS then
        ResetUnlocks( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == CREATE_SOUND then
        CreateSound( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == HIDE_HUD then
        ToggleHUD()
    elseif currentMenu.items[currentMenu.selectedIndex] == REVEAL_MAP then
        RevealMap( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == SHOW_LOADOUT then
        ShowLoadout( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_PHYSICS then
        TogglePhysicsDebug( pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_PATHING then
        TogglePathfindingDebug( pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_LIGHTING then
        ToggleLightingDebug(pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_FOW then
        ToggleFOWDebug(pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_SOUND then
        ToggleSoundDebug(pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_TRIGGER then
        ToggleTriggerDebug(pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == TOGGLE_CAMERA then
        ToggleCameraDebug(pSimulation)
    elseif currentMenu.items[currentMenu.selectedIndex] == CHECKPOINT_TELEPORT then
        if bPaused then
            TogglePause( pSimulation )
        end
        CheckpointTeleport( pSimulation )
    elseif currentMenu.items[currentMenu.selectedIndex] == SELECTION_PAGE_NEXT then
        pageNum = pageNum + 1
        UpdateDebugString(0)
        SingleStep()
    elseif currentMenu.items[currentMenu.selectedIndex] == SELECTION_PAGE_PREV then
        pageNum = pageNum + 0
        UpdateDebugString(0)
        SingleStep()
    elseif currentMenu.items[currentMenu.selectedIndex] == CHECKPOINT_SWITCH then
        if action == -1 then
            PrevCheckPoint( pSimulation )
            UpdateDebugString(0)
        else
            NextCheckPoint( pSimulation )
            UpdateDebugString(0)
        end
        SingleStep()
    elseif currentMenu.items[currentMenu.selectedIndex] == PROFILE_COLLISION then
        RunCollisionProfile( pSimulation, 1024, 100000 )
    elseif currentMenu.items[currentMenu.selectedIndex] == SELECTION_BACK or action == -1 then
        MenuBackAction()
    elseif (currentMenu.items[currentMenu.selectedIndex] == SELECTION_GUARDS or
            currentMenu.items[currentMenu.selectedIndex] == SELECTION_PROPS or
            currentMenu.items[currentMenu.selectedIndex] == SELECTION_LIGHTS or
            currentMenu.items[currentMenu.selectedIndex] == SELECTION_DOORS or
            currentMenu.items[currentMenu.selectedIndex] == SELECTION_HIDINGSPOTS or
            currentMenu.items[currentMenu.selectedIndex] == SELECTION_OTHER or
            currentMenu.items[currentMenu.selectedIndex] == HELP_MENU or
            currentMenu.items[currentMenu.selectedIndex] == PROFILE_TESTS) then
        currentMenu = menuList[currentMenu.items[currentMenu.selectedIndex]]
        pageNum = 0
        UpdateDebugString(0)
    elseif (string.find(currentMenu.items[currentMenu.selectedIndex], "==") == nil) then
        SpawnCharacterAtMouse( pSimulation, currentMenu.items[currentMenu.selectedIndex] ) 
        if bIsPaused then
            SingleStep()
        end
    end

end

function ToggleDebugMenu()
    if DebugTable.DebugString == "" then
        UpdateDebugString(0)
    else
        DebugTable.DebugString = ""
        SingleStep()
    end
end

DebugTable =
{
    DebugString = ""
}


BindKeys = 
{
    {
        KeyCombo = "ALT+1",
        Function = "SetCheckpoint( pSimulation, 0 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+2",
        Function = "SetCheckpoint( pSimulation, 1 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+3",
        Function = "SetCheckpoint( pSimulation, 2 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+4",
        Function = "SetCheckpoint( pSimulation, 3 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+5",
        Function = "SetCheckpoint( pSimulation, 4 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+6",
        Function = "SetCheckpoint( pSimulation, 5 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+7",
        Function = "SetCheckpoint( pSimulation, 6 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+8",
        Function = "SetCheckpoint( pSimulation, 7 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+9",
        Function = "SetCheckpoint( pSimulation, 8 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "ALT+0",
        Function = "SetCheckpoint( pSimulation, 9 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+1",
        Function = "SetCheckpoint( pSimulation, 10 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+2",
        Function = "SetCheckpoint( pSimulation, 11 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+3",
        Function = "SetCheckpoint( pSimulation, 12 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+4",
        Function = "SetCheckpoint( pSimulation, 13 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+5",
        Function = "SetCheckpoint( pSimulation, 14 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+6",
        Function = "SetCheckpoint( pSimulation, 15 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+7",
        Function = "SetCheckpoint( pSimulation, 16 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+8",
        Function = "SetCheckpoint( pSimulation, 17 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+9",
        Function = "SetCheckpoint( pSimulation, 18 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "SHIFT+0",
        Function = "SetCheckpoint( pSimulation, 19 ) UpdateDebugString(0)"
    },
    {
        KeyCombo = "JKEY_LStick",
        Function = "if bPaused then TogglePause( pSimulation ) elseif IsButtonDown('BUTTON_L1') then TogglePause( pSimulation ) if not bPaused then DebugRenderOn() end end"
        --Function = "ToggleHUD()"
    },
    {
        KeyCombo = "JKEY_RStick",
        --Function = "if bPaused then ToggleGodMode( pSimulation ) SingleStep() end"
        Function = "ToggleDebugMenu()",
    },
    {
        KeyCombo = "JKEY_LTrigger",
        Function = "if bPaused then PrevCheckPoint( pSimulation ) SingleStep() end"
    },
    {
        KeyCombo = "JKEY_RTrigger",
        Function = "if bPaused then NextCheckPoint( pSimulation ) SingleStep() end"
    },
    {
        -- WARNING you can't just change the IsButtonDown('BUTTON_L1') here to change the combo, because the map is bound to Back, and needs to know to ignore the keypress in code as well --bmiles
        KeyCombo = "JKEY_BACK",
        Function = "if IsButtonDown('BUTTON_L1') then TogglePause( pSimulation ) if not bPaused then DebugRenderOn() end end"
    },
    {
        KeyCombo = "JKEY_DPad_Left",
        Function = "if DebugTable.DebugString ~= \"\" then DebugAction(-1) else if bPaused then Rewind(5) end end"
    },
    {
        KeyCombo = "JKEY_DPad_Right",
        Function = "if DebugTable.DebugString ~= \"\" then DebugAction(1) else if bPaused then Advance(5) end end"
    },
    {
        KeyCombo = "JKEY_DPad_Up",
        Function = "if DebugTable.DebugString ~= \"\" then UpdateDebugString(-1) else if bPaused then Advance(1) end end"
    },
    {
        KeyCombo = "JKEY_DPad_Down",
        Function = "if DebugTable.DebugString ~= \"\" then UpdateDebugString(1) else if bPaused then Rewind(1) end end"
    },
    {
        KeyCombo = "JKEY_RBumper",
        --Function = "UpdateDebugString(1)"
        Function = "if bPaused then DebugNextGameItem() end"
    },
    {
        KeyCombo = "JKEY_LBumper",
        --Function = "UpdateDebugString(-1)"
        Function = "if bPaused then DebugPrevGameItem() end"
        --Function = "if bPaused then DebugPrevGameItem() else TogglePause( pSimulation ) end"
    },

    {
        KeyCombo = "JKEY_YBtn",
        Function = "if bPaused then ToggleHUD() end"
        --Function = "if bPaused then TogglePause( pSimulation ) Reload( pSimulation ) end"
    },

    {
        KeyCombo = "JKEY_XBtn",
        Function = "if bPaused then ToggleDebugRender() end"
    },

    {
        KeyCombo = "JKEY_BBtn",
        Function = "if bPaused then CycleDebugSpew(false) end"
        --Function = "if bPaused then ToggleSuperSpeed() end"
    },
    
    {
        KeyCombo = "JKEY_ABtn",
        Function = "if bPaused then TabPressed() end"
    },
    {
        KeyCombo = "CTRL+K",
        Function = "KillDebugCharacter() SingleStep()"
    },
    {
        KeyCombo = "CTRL+I",
        Function = "ToggleInvisibility( pPlayer1 )"
    },
    {
        KeyCombo = "CTRL+N",
        Function = "PrevCheckPoint( pSimulation )"
    },
    {
        KeyCombo = "CTRL+M",
        Function = "PrevCheckPoint( pSimulation )"
    },
    {
        KeyCombo = "CTRL+U",
        Function = "ToggleSuperSpeed()"
    },
    {
        KeyCombo = "CTRL+G",
        Function = "ToggleGodMode( pSimulation )"
    },
    {
        KeyCombo = "CTRL+L",
        Function = "LoadDebugFile()"
    },
    {
        KeyCombo = "L",
        Function = "CheckLit( pSimulation )"
    },
    {
        KeyCombo = "KEY_F2",
        Function = "CycleDebugSpew(false)"
    },
    {
        KeyCombo = "SHIFT+KEY_F2",
        Function = "CycleDebugSpew(true)"
    },
    {
        KeyCombo = "CTRL+W",
        Function = "SetGameOver( pSimulation, 3 )" -- Level Complete
    },
    {
        KeyCombo = "CTRL+F",
        Function = "SetGameOver( pSimulation, -2 )" -- Level Failed
    },  
    {
        KeyCombo = "CTRL+S",
        Function = "SaveProfiles()"
    },
    {
        KeyCombo = "CTRL+SHIFT+P",
        Function = "PurchaseDebugGameLicense( )"
    },
    {
        KeyCombo = "CTRL+P",
        Function = "TogglePathfindingDebug( pSimulation)",
    },
    {
        KeyCombo = "CTRL+O",
        Function = "TogglePhysicsDebug( pSimulation)",
    },
    {
        KeyCombo = "CTRL+A",
        Function = "RefillAmmo( pPlayer1 )"
    },
    {
        KeyCombo = "CTRL+Y",
        Function = "CreateSound( pSimulation )"
    },
    {
        KeyCombo = "CTRL+T",
        Function = "CheckpointTeleport( pSimulation )"
    },
    {
        KeyCombo = "X",
        Function = "TeleportPlayer( pSimulation )"
    },
    {
        KeyCombo = "I",
        Function = "LookAtMouse( pSimulation )"
    },
    {
        KeyCombo = "CTRL+R",
        Function = "if bPaused then TogglePause( pSimulation ) end Reload( pSimulation )"
    },
    {
        KeyCombo = "CTRL+SHIFT+R",
        Function = "if bPaused then TogglePause( pSimulation ) end ReloadAtLastCheckpoint( pSimulation )"
    },
}

game_object_list.lua#

-- Game object list used for debug purposes:
guards =
{
    "azai_boss",
    "guard_assaulter",
    "guard_assaulter_desert",
    "guard_assaulter_w4",
    "guard_dog",
    "guard_stalker",
    "hostage_azai",
    "hostage_dosan",
    "hostage_ninja",
    "karajan",
    "karajan_walk",
    "med_guard_civilian",
    "med_guard_defender",
    "med_guard_defender_desert",
    "med_guard_defender_w4",
    "med_guard_gasmask",
    "med_guard_gasmask_desert",
    "med_guard_gasmask_w4",
    "med_guard_melee_key",
    "med_guard_rifle",
    "med_guard_rifle_desert",
    "med_guard_rifle_desert_key",
    "med_guard_rifle_target",
    "med_guard_rifle_w4",
    "med_guard_rifle_yellow",
    "med_guard_rifle_yellow_key",
    "med_guard_rifle_yellow_key_a",
    "med_guard_rifle_yellow_key_b",
    "med_guard_shrink",
    "med_guard_shrink_double",
    "med_guard_sniper",
    "med_guard_sniper_desert",
    "med_guard_sniper_w4",
    "merc_captain",
    "merc_captain_noshadow",
    "ora",
    "ora_ai",
    "ora_ai_ending",
    "ora_ai_small",
    "ora_ai_with_vision",
}
lights =
{
    "1-3_skylight_break",
    "alarm_light",
    "chandelier_apart",
    "chandelier_apart_w2",
    "chandelier_apart_w3",
    "chandelier_apart_w4",
    "chandelier_whole",
    "chandelier_whole_w3",
    "chandelier_whole_w4",
    "crank_light",
    "crank_light_wide",
    "draggable_lightbox",
    "face_light_mask_1",
    "face_light_mask_1_left_eye",
    "face_light_mask_1_right_eye",
    "falling_light_fuse_bottom",
    "falling_light_fuse_top",
    "falling_light_hook",
    "falling_light_rig",
    "falling_light_rig2",
    "light_candle_1_w4",
    "light_candle_2_w4",
    "light_candle_3_w4",
    "light_economic_ext_01",
    "light_economic_ext_02",
    "light_economic_ext_03",
    "light_economic_int_01",
    "light_economic_int_02",
    "light_economic_int_03",
    "light_economic_int_04",
    "light_economic_int_05",
    "light_economic_int_06",
    "light_economic_int_07",
    "light_economic_int_08",
    "light_economic_int_09",
    "light_economic_int_emergency_01",
    "light_economic_int_pointlight",
    "light_perchpoint_w4",
    "light_w2_ext_01",
    "light_w2_ext_02",
    "light_w2_ext_03",
    "light_w2_ext_04",
    "light_w2_ext_05",
    "light_w2_ext_06",
    "light_w2_int_02",
    "light_w2_int_03",
    "light_w2_int_04",
    "light_w2_int_05",
    "light_w2_int_06",
    "light_w3_ext_01",
    "light_w3_ext_02",
    "light_w3_ext_03",
    "light_w3_ext_04",
    "light_w3_ext_05",
    "light_w3_ext_06",
    "light_w3_int_01",
    "light_w3_int_02",
    "light_w3_int_03",
    "light_w3_int_04",
    "light_w3_int_05",
    "light_w3_int_06",
    "light_w3_int_07",
    "light_w4_ext_01",
    "light_w4_ext_02",
    "light_w4_ext_03",
    "light_w4_ext_05",
    "light_w4_ext_06",
    "light_w4_ext_07",
    "light_w4_ext_08",
    "light_w4_int_01",
    "light_w4_int_02",
    "light_w4_int_03",
    "light_w4_int_04",
    "light_w4_int_05",
    "light_w4_int_06",
    "light_w4_int_07",
    "light_w4_int_08",
    "light_w4_swing_tutorial",
    "projectile_distractlight",
    "rail_search_light",
    "rail_search_light_no_target",
    "rail_search_light_wide",
    "rail_turret_light_activated",
    "sensor_light",
    "sensor_light_4_2",
    "sensor_light_eye_left",
    "sensor_light_eye_right",
    "sensor_light_on",
    "sensor_light_toggle",
    "standing_light",
    "switch_light",
    "wall_disappear_light",
}
doors =
{
    "block_ceiling_vent",
    "block_floor_vent",
    "block_side_vent",
    "closet_door",
    "closet_door_w2",
    "closet_door_w3",
    "closet_door_w4",
    "collectible_scroll_vent",
    "door",
    "door_ceiling_w2",
    "door_crank",
    "door_elevator",
    "door_hinge",
    "door_locked",
    "door_power_sealed",
    "door_power_sealed_w4",
    "door_trap",
    "door_trigger_w4",
    "door_unlockable",
    "door_unlockable_w2",
    "door_unlockable_w3",
    "door_unlockable_w4",
    "door_w2",
    "door_w3",
    "door_w4",
    "healthbox_vents",
    "spawner_door",
    "spawner_door_norecall",
    "spawner_door_shrink",
    "spawner_door_w1",
    "vent_4x1",
    "vent_4x1_locked",
    "vent_4x2",
    "vent_bg_wall_w2",
    "vent_fan",
    "vent_flameduct",
    "vent_horiz",
    "vent_power_door",
    "vent_vertical",
}
hidingspots =
{
    "closet",
    "closet_w2",
    "closet_w3",
    "closet_w4",
    "dumpster",
    "hiding_spot_alcove",
    "hiding_spot_alcove_01_w3",
    "hiding_spot_alcove_01_w4",
    "hiding_spot_alcove_ug_01_w4",
    "hiding_spot_alcove_underground",
    "hiding_spot_alcove_underground_w2",
    "hiding_spot_alcove_underground_w3",
    "hiding_spot_alcove_w2",
    "hiding_spot_altar2_int_w3",
    "hiding_spot_altar_01_w3",
    "hiding_spot_altar_02_w3",
    "hiding_spot_armor",
    "hiding_spot_armour_01_w4",
    "hiding_spot_bin",
    "hiding_spot_bin_2_w2",
    "hiding_spot_bin_3_w2",
    "hiding_spot_bonsai_ext_01_w4",
    "hiding_spot_chimney_01",
    "hiding_spot_chimney_02",
    "hiding_spot_chimney_ext_01_w4",
    "hiding_spot_dragon_01_w4",
    "hiding_spot_pillar",
    "hiding_spot_pillar_break_w3",
    "hiding_spot_plant",
    "hiding_spot_plant_01_w3",
    "hiding_spot_screen_01_w4",
    "hiding_spot_statue_ext_01_w4",
    "hiding_spot_urn",
    "hiding_spot_urn_01_trap_w3",
    "hiding_spot_urn_01_w3",
    "hiding_spot_urn_02_trap_w3",
    "hiding_spot_urn_02_w3",
    "hiding_spot_urn_03_trap_w3",
    "hiding_spot_urn_03_w3",
}
other =
{
    "0_1_bell",
    "0_1_preloader",
    "1-3_air_intake",
    "1-3_air_intake_switch",
    "1-3_fuse_breaker_1",
    "1-3_fuse_breaker_2",
    "1-3_fuse_breaker_3",
    "1-3_fuse_breaker_4",
    "1-3_fuse_breaker_5",
    "1-3_fuse_panel",
    "1-3_fuse_top_wires",
    "1-3_gas_pipes",
    "1-3_rooftop_flammable",
    "1_1_preloader",
    "1_2_preloader",
    "1_3_preloader",
    "1_4_crate_switch",
    "1_4_moving_crate",
    "1_4_preloader",
    "2-2_crate_switch",
    "2-2_moving_crate",
    "2-2_sarcophagus",
    "2-4_moving_crate_noclimb",
    "2_1_preloader",
    "2_2_cogs",
    "2_2_preloader",
    "2_3_preloader",
    "2_4_damageregion",
    "2_4_dosan_desk",
    "2_4_preloader",
    "3_1_dosan_sumi",
    "3_1_dosan_tools",
    "3_1_preloader",
    "3_2_cr_control",
    "3_2_cr_damageregion",
    "3_2_preloader",
    "3_dlc_preloader",
    "3_dlc_trap_scripttrigger",
    "4-2_mask_weakness",
    "4-2_shrine",
    "4_1_armor_lever",
    "4_1_preloader",
    "4_2_bell",
    "4_2_preloader",
    "ammo_box_darknessbugs",
    "ammo_box_gasbomb",
    "ammo_box_noisemaker",
    "ammo_box_shuriken",
    "ammo_box_smokebomb",
    "ammo_box_spikemine",
    "ammo_box_toxicspores",
    "bioscanner",
    "bombs_hanging_parts_w4",
    "bombs_hanging_w4",
    "bone_spikes",
    "breakable_ceiling_w4",
    "breakable_floor_w4",
    "breaking_overhang",
    "breaking_tile",
    "bridge",
    "bullet",
    "carbomb_1",
    "carbomb_2",
    "cave_in_w3",
    "chair",
    "challenge_room_gate",
    "challenge_room_plugs",
    "checkpoint_marker",
    "collapse_bridge",
    "collapsing_bridge_piece",
    "collapsing_perch",
    "collapsing_perch_apart_w3",
    "collapsing_perch_underground_w2",
    "collapsing_perch_w3",
    "collectible_box",
    "collectible_box_objective_1",
    "collectible_box_objective_2",
    "collectible_dart",
    "collectible_grapple",
    "collectible_scroll",
    "collectible_sword",
    "crank_crate_horiz",
    "crank_crate_vert",
    "crusher",
    "crusher_up",
    "dangle_hang_rope",
    "dosan",
    "dosans_grave",
    "draggable_box",
    "draggable_box_fragile_w2",
    "draggable_box_w2",
    "electric_floor",
    "electric_panel_w3",
    "electric_pole",
    "electric_pole_damage",
    "electric_wall",
    "elevator",
    "farsight",
    "flag_01",
    "flag_01_decor_w4",
    "flag_02_tattered",
    "flame_jets",
    "flare",
    "floor_spikes_w3",
    "fow_burner",
    "fow_burner_stealthkill",
    "fuel_pump",
    "fusebox",
    "fusebox_nofog",
    "gasmain",
    "gasmain_trap",
    "gears",
    "gears_fiery",
    "gears_fire_chase",
    "gears_switch_box",
    "generator",
    "generator_small_w3",
    "gong",
    "gong_w3",
    "grenade",
    "grenade_gas",
    "ground_shatter",
    "hallucination_tree",
    "hazard_hang_w3_1",
    "hazard_hang_w3_2_apart",
    "hazard_hang_w3_2_whole",
    "hazard_hang_w3_3_apart",
    "hazard_hang_w3_3_whole",
    "hazard_vines",
    "hazard_vines_lever",
    "healthbox",
    "helicopter",
    "hessian_goods_1",
    "hessian_goods_2",
    "hessian_goods_3",
    "hessian_goods_4",
    "ied_hanging_1",
    "ied_hanging_3_2",
    "ied_part_1",
    "ied_part_3_2",
    "key_item",
    "key_item_a",
    "key_item_b",
    "lever",
    "lever_2_4",
    "lever_4_2",
    "lever_crank",
    "lever_crank_hold",
    "lever_crank_up",
    "lever_w4",
    "lever_w4_bg_chains",
    "lever_w4_bg_chains_single",
    "loadout_box",
    "loadout_upgrades_box",
    "manhole_cover",
    "mask_eyefollow",
    "mask_horror",
    "merc_capt_grenade",
    "motion_sensor",
    "moving_platform",
    "needle_bomb",
    "noisemaker_prop_w1",
    "noisemaker_prop_w2_hanging",
    "noisemaker_prop_w2_standing",
    "noisemaker_prop_w3",
    "noisemaker_prop_w4",
    "noisemaker_prop_w4_hanging",
    "objective",
    "power_timed_toggle",
    "pressure_switch",
    "pressure_switch_w3",
    "projectile_bodyconsume",
    "projectile_caltrop",
    "projectile_caltrop_trap",
    "projectile_darknessbugs",
    "projectile_dart",
    "projectile_firedart",
    "projectile_flashbomb",
    "projectile_flashmine",
    "projectile_gasbomb",
    "projectile_grapplinghook",
    "projectile_noisemaker",
    "projectile_noisemaker_tute",
    "projectile_shuriken",
    "projectile_smokebomb",
    "projectile_spikemine",
    "projectile_terrordart",
    "projectile_throwingknife",
    "projectile_toxicspores",
    "radio_large",
    "rail_turret_grenade",
    "rail_turret_grenade_piece",
    "rail_turret_grenade_sound",
    "rail_turret_laser",
    "rat",
    "raven",
    "security_camera",
    "sensor_sound",
    "sensor_sound_off",
    "se_commentary_glow",
    "se_commentary_prop",
    "shield",
    "sound_emitter",
    "spear_trap",
    "spike_trap",
    "stairway",
    "stairway_02",
    "steam_pipe",
    "switch_can_use_once",
    "switch_normal",
    "switch_pass",
    "switch_wall",
    "sword_rack_final",
    "table_chairs",
    "terror_object_01",
    "timestop_anchor",
    "toggle_hit_switch",
    "toggle_switch",
    "tracker_item",
    "train",
    "train_body",
    "train_tail",
    "transformer",
    "transformer_wires",
    "trap_dart",
    "trap_darts",
    "trap_swing_blade",
    "trip_wire",
    "trip_wire_chain",
    "trip_wire_explode",
    "trip_wire_explode_w2",
    "trip_wire_power",
    "trip_wire_rope",
    "trip_wire_ropeplayeronly",
    "turret_grenade",
    "vase_breakable",
    "wall_mounted_lamp",
    "wall_mounted_lamp_proximity",
    "wall_mounted_lamp_wide",
    "wavecontroller2_2",
    "window",
    "wires_exposed",
    "wires_exposed_6t",
}

Unused / Test Levels#

This game has 13 real levels and almost 40 unused ones. Cool, huh?

Please elaborate.
Having more detail is always a good thing.
Specifically: describe the rest of the levels

Open /data/levels.lua. Find this line:

filename= [[0_1]],

Change the part in brackets to one of these:

  • 1_ninjatest
  • 4_1_levelflow (has nothing to do with the actual 4-1 despite the name)
  • combat_test
  • commentary_test
  • farsightest
  • finalarea_test
  • navtest
  • scroll_test (This has every scroll in the game. Get some free achievements!)
  • se
  • stealth_kill_row

Then launch the game and start the tutorial level to discover some secret ninja goodies. (Be sure to select "restart" instead of "continue" when switching filenames, or else the game will crash!)

se (Special Edition DLC Level)#

This isn't actually an unused level - rather, it's the bonus level from the Special Edition DLC, fully present and playable in the original game!

Obviously, you'll be playing it as the ninja instead of Dosan, and there is some occasional weirdness (blank dialogs popping up from time to time), but the level is completely playable out of the box. The dusk moths and fungal spores are still present and fully usable, but they aren't actually added to any of your inventory slots when picked up, so you won't be able to use them again after switching items. Also, any seals or achievements related to the new items can't be obtained this way.

1_ninjatest#

320px320px320px

This one is an unused level, and features some beautiful blue squares and a dark cloudy background. The level consists of some basic structures with slopes, grates, grapple points, and a few guards scattered around. Also, at the upper left corner of the level there is a small photo of a helicopter for some reason.

4_1_levelflow#

320px320px

combat_test#

320px320px

commentary_test#

320px320px

farsightest#

320px320px

finalarea_test#

320px

320px320px

scroll_test#

320px320px

stealth_kill_row#

320px320px320px

Other Levels#

There are lots of other unused levels in the /data-pc/levels directory which aren't playable for various reasons; they all either crash the game or kick you back to the main menu immediately. Most of them lack the file "objectives.lua" but transplanting one from existing levels doesn't do anything.

  • 0_1_old
  • 0_1_tutorialtest
  • 3_1_van
  • blend_test
  • ceremonial_chamber_levelflow
  • challenge_art_test
  • challenge_art_test2
  • collision_test
  • combat_progression
  • meg_test
  • meg_test_blue
  • meg_test_world2
  • meg_test_world4
  • meg_test_world4_2
  • meg_test_world4_3
  • music_test
  • ora_test
  • sound_filter_test
  • teaser_trailer
  • test_dog
  • test_groupsearch
  • test_objectives
  • test_sc
  • test_scrolls
  • test_seals
  • test_vents
  • testdr_sc
  • vertical_slice
  • vs