From e08d934dbdf479ea6605bc3c0e30dd2bdc1b1bc8 Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Fri, 4 Sep 2026 06:28:59 -0700 Subject: [PATCH] [jak3] Add autosplits for side mission golds, orbs per level (#4398) For hundo, all satellite, all open orbs gamers Goes along with https://github.com/open-goal/speedrunning/pull/35 --- goal_src/jak3/engine/game/game-info.gc | 134 +++++++++++++++++- goal_src/jak3/engine/util/script.gc | 3 +- goal_src/jak3/levels/city/ctywide-obs.gc | 3 +- .../city/port/attack/ctyport-attack-bbush.gc | 3 +- .../jak3/levels/common/race/race-manager.gc | 3 +- .../jak3/levels/desert/des-bbush-tasks.gc | 3 +- goal_src/jak3/levels/desert/des-bush.gc | 12 +- .../desert/rescue/desert-rescue-bbush.gc | 3 +- .../wascity/bbush/des-bush-time-chase.gc | 3 +- .../jak3/levels/wascity/wasgun-manager.gc | 9 +- goal_src/jak3/pc/features/autosplit-h.gc | 31 +++- goal_src/jak3/pc/features/autosplit.gc | 31 +++- 12 files changed, 219 insertions(+), 19 deletions(-) diff --git a/goal_src/jak3/engine/game/game-info.gc b/goal_src/jak3/engine/game/game-info.gc index 00d11f9e15..f41fbfe3ab 100644 --- a/goal_src/jak3/engine/game/game-info.gc +++ b/goal_src/jak3/engine/game/game-info.gc @@ -16,6 +16,132 @@ (define-extern *highscore-info-array* (array highscore-info)) (define-extern *user* symbol) +;; og:preserve-this added enum and helper functions to map orbs to money-per-level index +(defenum level-money-data-index + :type int32 + (vinroom 0) + (ctygenb 1) + (ctysluma 2) + (ctyslumb 3) + (ctyslumc 4) + (ctyport 5) + (ctyinda 6) + (ctyindb 7) + (stadium 8) + (gungame 9) + (sewb 10) + (sewd 11) + (sewh 12) + (sewm 13) + (sewo 14) + (wascitya 15) + (wascityb 16) + (wasstada 17) + (waspala 18) + (desert 19) + (nsta 20) + (templex 21) + (templeb 22) + (templed 23) + (max 24) + ) + +(defun level-money-data-remap ((lvl-idx int)) + (case lvl-idx + ((4) (level-money-data-index vinroom)) + ((32) (level-money-data-index ctygenb)) + ((33) (level-money-data-index ctysluma)) + ((34) (level-money-data-index ctyslumb)) + ((36) (level-money-data-index ctyslumc)) + ((37) (level-money-data-index ctyport)) + ((40) (level-money-data-index ctyinda)) + ((41) (level-money-data-index ctyindb)) + ((42) (level-money-data-index stadium)) + ((73) (level-money-data-index gungame)) + ((110) (level-money-data-index sewb)) + ((112) (level-money-data-index sewd)) + ((116) (level-money-data-index sewh)) + ((121) (level-money-data-index sewm)) + ((123) (level-money-data-index sewo)) + ((136) (level-money-data-index wascitya)) + ((138) (level-money-data-index wascityb)) + ((151) (level-money-data-index wasstada)) + ((197) (level-money-data-index waspala)) + ((141 200) (level-money-data-index desert)) ;; also include waspgame + ((252) (level-money-data-index nsta)) + ((257) (level-money-data-index templex)) + ((259) (level-money-data-index templeb)) + ((261) (level-money-data-index templed)) + (else + (format 0 "Found orb in unexpected level index ~D~%" lvl-idx) + (level-money-data-index max)) ;; shouldn't be orbs elsewhere, dump here in case + ) + ) + +(defun adjust-money-per-level ((info game-info) (amount float) (arg2 handle)) + (let* ((proc (handle->process arg2)) + (parent-proc (ppointer->process (-> proc parent)))) + (when (and (ppointer->process (-> proc parent)) (type-type? (-> (ppointer->process (-> proc parent)) type) task-manager)) + ;; task-managers (and any child orbs) grab the 0th entity from the task's level (see task-manager-init-by-other) + ;; e.g. des-burning-bush-18 in wascitya => task-manager chooses 0th entity camera-start-164 from waswide + ;; we want wascitya rather than waswide, so we map via task-manager's node-info task instead of by entity level + (set! proc (the task-manager parent-proc))) + (cond + ((and proc (type-type? (-> proc type) task-manager)) + ;; side mission orb + (let ((level-idx + (case (-> (the task-manager proc) node-info task) + (((game-task city-jetboard-bbush)) + (level-money-data-index ctyinda)) + (((game-task desert-bbush-get-to-1) (game-task desert-bbush-get-to-2) (game-task desert-bbush-get-to-3) + (game-task desert-bbush-get-to-4) (game-task desert-bbush-get-to-5) (game-task desert-bbush-get-to-6) + (game-task desert-bbush-get-to-7) (game-task desert-bbush-get-to-8) (game-task desert-bbush-get-to-9) + (game-task desert-bbush-get-to-11) (game-task desert-bbush-get-to-12) (game-task desert-bbush-get-to-14) + (game-task desert-bbush-get-to-16) (game-task desert-bbush-get-to-17) (game-task desert-bbush-ring-1) + (game-task desert-bbush-ring-2) (game-task desert-bbush-egg-spider-1) (game-task desert-bbush-spirit-chase-1) + (game-task desert-bbush-timer-chase-1) (game-task desert-bbush-air-time) (game-task desert-bbush-total-air-time) + (game-task desert-bbush-jump-distance) (game-task desert-bbush-total-jump-distance) (game-task desert-bbush-roll-count) + (game-task desert-bbush-time-trial-1) (game-task desert-bbush-rally) (game-task desert-rescue-bbush) + (game-task desert-bbush-destroy-interceptors)) + (level-money-data-index desert)) + (((game-task wascity-bbush-get-to-18) (game-task desert-bbush-get-to-19) (game-task wascity-bbush-get-to-20) + (game-task wascity-bbush-get-to-21) (game-task wascity-bbush-ring-4) (game-task wascity-bbush-timer-chase-2)) + (level-money-data-index wascitya)) + (((game-task wascity-bbush-get-to-22) (game-task wascity-bbush-get-to-23) (game-task wascity-bbush-get-to-24) + (game-task wascity-bbush-get-to-25) (game-task wascity-bbush-ring-3) (game-task wascity-bbush-spirit-chase-2) + (game-task wascity-gungame)) + (level-money-data-index wascityb)) + (((game-task city-bbush-get-to-26) (game-task city-bbush-get-to-28) (game-task city-bbush-get-to-29) + (game-task city-bbush-get-to-30)) + (level-money-data-index ctygenb)) + (((game-task city-bbush-get-to-27) (game-task city-bbush-get-to-31) (game-task city-bbush-ring-5)) + (level-money-data-index ctyslumb)) + (((game-task city-bbush-get-to-32) (game-task city-bbush-get-to-33) (game-task city-bbush-spirit-chase-3)) + (level-money-data-index ctyslumc)) + (((game-task city-bbush-get-to-34) (game-task city-bbush-get-to-35)) + (level-money-data-index ctysluma)) + (((game-task city-bbush-get-to-36) (game-task city-bbush-get-to-37)) + (level-money-data-index ctyindb)) + (((game-task city-bbush-get-to-38) (game-task city-bbush-get-to-39) (game-task city-bbush-get-to-40) + (game-task city-bbush-ring-6) (game-task city-jetboard-bbush)) + (level-money-data-index ctyinda)) + (((game-task city-bbush-get-to-41) (game-task city-bbush-get-to-42) (game-task city-bbush-get-to-43) + (game-task city-bbush-get-to-44) (game-task city-bbush-port-attack)) + (level-money-data-index ctyport)) + (else + (format 0 "adjust-money-per-level: unhandled orb! unexpected task-manager ~A ~A~%" proc (-> (the task-manager proc) node-info task)) + (level-money-data-index max)) + ))) + (+! (-> info money-per-level level-idx) (the int amount)))) + ((and proc (-> proc entity)) + ;; open orb/crate/urn, or from power-game/was-pre-game + (let ((level-idx (level-money-data-remap (-> proc entity extra level info index)))) + (+! (-> info money-per-level level-idx) (the int amount)))) + (else + (format 0 "adjust-money-per-level: unhandled orb! no entity/task-manager~A~%" proc) + ))) + (none)) + ;; DECOMP BEGINS (defmethod debug-draw ((this border-plane)) @@ -732,9 +858,11 @@ (set! (-> this gem) (+ (-> this gem) arg1)) ) (('skill) - (if (< 0.0 arg1) - (+! (-> this skill-total) arg1) - ) + ;; og:preserve-this added logic for tracking orbs per level + (when (< 0.0 arg1) + (adjust-money-per-level this arg1 arg2) + (+! (-> this skill-total) arg1) + ) (+! (-> this skill) arg1) (if (< 0.0 arg1) (menu-secrets-notify-powerup-collect) diff --git a/goal_src/jak3/engine/util/script.gc b/goal_src/jak3/engine/util/script.gc index 04fb3fb3be..6b4aeb03ef 100644 --- a/goal_src/jak3/engine/util/script.gc +++ b/goal_src/jak3/engine/util/script.gc @@ -3623,7 +3623,8 @@ (the-as pickup-type s5-0) (command-get-float (-> arg0 param 3) 0.0) #t - *entity-pool* + ;; og:preserve-this spawn from script-calling process, for money-per-level tracking + (-> arg0 process) s4-0 ) ) diff --git a/goal_src/jak3/levels/city/ctywide-obs.gc b/goal_src/jak3/levels/city/ctywide-obs.gc index cd195c009a..4f95c93ae2 100644 --- a/goal_src/jak3/levels/city/ctywide-obs.gc +++ b/goal_src/jak3/levels/city/ctywide-obs.gc @@ -2927,7 +2927,8 @@ (send-event this 'fail) ) (else - (give *game-info* 'skill f30-0 (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill f30-0 (process->handle this)) (until (time-elapsed? (-> this state-time) (the int (* 45.0 f30-0))) (suspend) ) diff --git a/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc b/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc index d7c653a482..03d6ca4393 100644 --- a/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc +++ b/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc @@ -589,7 +589,8 @@ (until (= (-> *setting-control* user-current bg-a) 0.0) (suspend) ) - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (until (process-release? *target*) (suspend) ) diff --git a/goal_src/jak3/levels/common/race/race-manager.gc b/goal_src/jak3/levels/common/race/race-manager.gc index 5091303985..29ddda22e4 100644 --- a/goal_src/jak3/levels/common/race/race-manager.gc +++ b/goal_src/jak3/levels/common/race/race-manager.gc @@ -1020,7 +1020,8 @@ ) ) (set! sv-32 (game-info-method-27 *game-info* (the-as game-score sv-16) sv-20)) - (give *game-info* 'skill (the float s4-0) (the-as handle #f)) + ;; og:preserve-this pass handle to race-manager for money-per-level tracking + (give *game-info* 'skill (the float s4-0) (process->handle this)) ) (if (and (= s5-0 3) (= gp-0 3) (zero? sv-32)) (set! sv-24 #t) diff --git a/goal_src/jak3/levels/desert/des-bbush-tasks.gc b/goal_src/jak3/levels/desert/des-bbush-tasks.gc index b464d1e202..bb3f412d0b 100644 --- a/goal_src/jak3/levels/desert/des-bbush-tasks.gc +++ b/goal_src/jak3/levels/desert/des-bbush-tasks.gc @@ -454,7 +454,8 @@ (gp-1 (max 0 (- v1-2 s3-0))) ) (game-info-method-27 *game-info* (the-as game-score s5-0) arg0) - (give *game-info* 'skill (* (the float gp-1) (-> *FACT-bank* super-skill-inc)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (* (the float gp-1) (-> *FACT-bank* super-skill-inc)) (process->handle this)) ) 0 (none) diff --git a/goal_src/jak3/levels/desert/des-bush.gc b/goal_src/jak3/levels/desert/des-bush.gc index 1a4b066cae..77be981004 100644 --- a/goal_src/jak3/levels/desert/des-bush.gc +++ b/goal_src/jak3/levels/desert/des-bush.gc @@ -535,7 +535,8 @@ ) ) (task-manager-method-27 self) - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (until (< (* 45 (-> self info user-count)) (- (current-time) (-> self state-time))) (suspend) ) @@ -1374,7 +1375,8 @@ ) ) (task-manager-method-27 self) - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (until (< (* 45 (-> self info user-count)) (- (current-time) (-> self state-time))) (suspend) ) @@ -1595,7 +1597,8 @@ ) (task-manager-method-27 self) (set-time! (-> self state-time)) - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (set-action! *gui-control* (gui-action play) @@ -2112,7 +2115,8 @@ ) ) (task-manager-method-27 self) - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (until (< (* 45 (-> self info user-count)) (- (current-time) (-> self state-time))) (suspend) ) diff --git a/goal_src/jak3/levels/desert/rescue/desert-rescue-bbush.gc b/goal_src/jak3/levels/desert/rescue/desert-rescue-bbush.gc index 831563ed95..e6b884eb0e 100644 --- a/goal_src/jak3/levels/desert/rescue/desert-rescue-bbush.gc +++ b/goal_src/jak3/levels/desert/rescue/desert-rescue-bbush.gc @@ -260,7 +260,8 @@ :virtual #t :event task-manager-event-handler :code (behavior () - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (until (< (* 45 (-> self info user-count)) (- (current-time) (-> self state-time))) (suspend) ) diff --git a/goal_src/jak3/levels/wascity/bbush/des-bush-time-chase.gc b/goal_src/jak3/levels/wascity/bbush/des-bush-time-chase.gc index f8ffa08dcc..00bd2374be 100644 --- a/goal_src/jak3/levels/wascity/bbush/des-bush-time-chase.gc +++ b/goal_src/jak3/levels/wascity/bbush/des-bush-time-chase.gc @@ -1453,7 +1453,8 @@ ) ) (task-manager-method-27 self) - (give *game-info* 'skill (the float (-> self info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> self info user-count)) (process->handle self)) (until (< (* 45 (-> self info user-count)) (- (current-time) (-> self state-time))) (suspend) ) diff --git a/goal_src/jak3/levels/wascity/wasgun-manager.gc b/goal_src/jak3/levels/wascity/wasgun-manager.gc index 8207d89120..809c53a85e 100644 --- a/goal_src/jak3/levels/wascity/wasgun-manager.gc +++ b/goal_src/jak3/levels/wascity/wasgun-manager.gc @@ -2364,15 +2364,18 @@ ) (when (and (>= (-> this goal-amount) 1) (not (task-node-closed? (the-as game-task-node (-> this task-bronze))))) (task-node-close! (the-as game-task-node (-> this task-bronze)) 'event) - (give *game-info* 'skill (the float (-> this info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> this info user-count)) (process->handle this)) ) (when (and (>= (-> this goal-amount) 2) (not (task-node-closed? (the-as game-task-node (-> this task-silver))))) (task-node-close! (the-as game-task-node (-> this task-silver)) 'event) - (give *game-info* 'skill (the float (-> this info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> this info user-count)) (process->handle this)) ) (when (and (>= (-> this goal-amount) 3) (not (task-node-closed? (the-as game-task-node (-> this task-gold))))) (task-node-close! (the-as game-task-node (-> this task-gold)) 'event) - (give *game-info* 'skill (the float (-> this info user-count)) (the-as handle #f)) + ;; og:preserve-this pass handle to task-manager for money-per-level tracking + (give *game-info* 'skill (the float (-> this info user-count)) (process->handle this)) ) (none) ) diff --git a/goal_src/jak3/pc/features/autosplit-h.gc b/goal_src/jak3/pc/features/autosplit-h.gc index 0997e4d1d8..81b27f48ab 100644 --- a/goal_src/jak3/pc/features/autosplit-h.gc +++ b/goal_src/jak3/pc/features/autosplit-h.gc @@ -162,7 +162,36 @@ (int-city-bbush-get-to-31 uint8) ;; start bbush in new haven (harder any%+hero mode palace ruins) (int-city-bbush-get-to-28 uint8) ;; start bbush closest to palace ruins (no oob restricted palace ruins) (desert-final-boss-walker uint8) ;; terraformer - ;; TODO - orbs in level X + (wascity-pre-game-gold uint8) + (wascity-gungame-gold uint8) + (city-gun-course-1-gold uint8) + (city-gun-course-2-gold uint8) + (city-power-game-gold uint8) + ;; orbs per-level + (vinroom-num-orbs uint8) ;; Power Station (9 side) + (ctygenb-num-orbs uint8) ;; Main Town Ruins (8 open, 12 side) + (ctysluma-num-orbs uint8) ;; Slums (3 open, 16 side) + (ctyslumb-num-orbs uint8) ;; New Haven South (7 open, 16 side) + (ctyslumc-num-orbs uint8) ;; New Haven North (4 open, 6 side) + (ctyport-num-orbs uint8) ;; Port (30 open, 30 side) + (ctyinda-num-orbs uint8) ;; Industrial South (8 open, 37 side) + (ctyindb-num-orbs uint8) ;; Industrial North (5 open, 6 side) + (stadium-num-orbs uint8) ;; Stadium Ruins East (10 open) + (gungame-num-orbs uint8) ;; Gun Course (18 side) + (sewb-num-orbs uint8) ;; Sewers 3.1 (3 open) + (sewd-num-orbs uint8) ;; Sewers 3.3 (3 open) + (sewh-num-orbs uint8) ;; Sewers 2.3 (3 open) + (sewm-num-orbs uint8) ;; Sewers 1.2 (2 open) + (sewo-num-orbs uint8) ;; Sewers 1.4 (2 open) + (wascitya-num-orbs uint8) ;; Spargus East (27 open, 32 side) + (wascityb-num-orbs uint8) ;; Spargus West (21 open, 41 side) + (wasstada-num-orbs uint8) ;; Spargus Arena (3 open) + (waspala-num-orbs uint8) ;; Spargus Palace (5 open) + (desert-num-orbs uint8) ;; Wasteland (208 side) + (nsta-num-orbs uint8) ;; Metal Head Cave (8 open) + (templex-num-orbs uint8) ;; Monk Temple Exterior (3 open) + (templeb-num-orbs uint8) ;; Monk Temple Center (13 open) + (templed-num-orbs uint8) ;; Monk Temple Rescue Seem (1 open) ;; end marker just to make things look nice in a memory view (end-marker uint8 4)) (:methods diff --git a/goal_src/jak3/pc/features/autosplit.gc b/goal_src/jak3/pc/features/autosplit.gc index 8627a7b177..5760602522 100644 --- a/goal_src/jak3/pc/features/autosplit.gc +++ b/goal_src/jak3/pc/features/autosplit.gc @@ -244,7 +244,36 @@ (autosplit-flag-task-node-closed! int-city-bbush-get-to-31 city-bbush-get-to-31-introduction) ;; start bbush in new haven (harder any%+hero mode palace ruins) (autosplit-flag-task-node-closed! int-city-bbush-get-to-28 city-bbush-get-to-28-introduction) ;; start bbush closest to palace ruins (no oob restricted palace ruins) (autosplit-flag-task-node-closed! desert-final-boss-walker desert-final-boss-walker) ;; terraformer - + (autosplit-flag-task-node-closed! wascity-pre-game-gold wascity-pre-game-gold) + (autosplit-flag-task-node-closed! wascity-gungame-gold wascity-gungame-gold) + (autosplit-flag-task-node-closed! city-gun-course-1-gold city-gun-course-1-gold) + (autosplit-flag-task-node-closed! city-gun-course-2-gold city-gun-course-2-gold) + (autosplit-flag-task-node-closed! city-power-game-gold city-power-game-gold) + ;; orbs per level + (set! (-> this vinroom-num-orbs) (-> *game-info* money-per-level (level-money-data-index vinroom))) + (set! (-> this ctygenb-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctygenb))) + (set! (-> this ctysluma-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctysluma))) + (set! (-> this ctyslumb-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctyslumb))) + (set! (-> this ctyslumc-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctyslumc))) + (set! (-> this ctyport-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctyport))) + (set! (-> this ctyinda-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctyinda))) + (set! (-> this ctyindb-num-orbs) (-> *game-info* money-per-level (level-money-data-index ctyindb))) + (set! (-> this stadium-num-orbs) (-> *game-info* money-per-level (level-money-data-index stadium))) + (set! (-> this gungame-num-orbs) (-> *game-info* money-per-level (level-money-data-index gungame))) + (set! (-> this sewb-num-orbs) (-> *game-info* money-per-level (level-money-data-index sewb))) + (set! (-> this sewd-num-orbs) (-> *game-info* money-per-level (level-money-data-index sewd))) + (set! (-> this sewh-num-orbs) (-> *game-info* money-per-level (level-money-data-index sewh))) + (set! (-> this sewm-num-orbs) (-> *game-info* money-per-level (level-money-data-index sewm))) + (set! (-> this sewo-num-orbs) (-> *game-info* money-per-level (level-money-data-index sewo))) + (set! (-> this wascitya-num-orbs) (-> *game-info* money-per-level (level-money-data-index wascitya))) + (set! (-> this wascityb-num-orbs) (-> *game-info* money-per-level (level-money-data-index wascityb))) + (set! (-> this wasstada-num-orbs) (-> *game-info* money-per-level (level-money-data-index wasstada))) + (set! (-> this waspala-num-orbs) (-> *game-info* money-per-level (level-money-data-index waspala))) + (set! (-> this desert-num-orbs) (-> *game-info* money-per-level (level-money-data-index desert))) + (set! (-> this nsta-num-orbs) (-> *game-info* money-per-level (level-money-data-index nsta))) + (set! (-> this templex-num-orbs) (-> *game-info* money-per-level (level-money-data-index templex))) + (set! (-> this templeb-num-orbs) (-> *game-info* money-per-level (level-money-data-index templeb))) + (set! (-> this templed-num-orbs) (-> *game-info* money-per-level (level-money-data-index templed))) ;; debug only, draw stuff to the screen so i don't have to stare at a memory editor (if AUTOSPLITTER_DEBUG (debug-draw this)))