@@ -244,16 +244,21 @@ export class GdlRuntime {
244244 }
245245
246246 private resolveModTypePath ( mt : ModTypeDecl , ctx : ResolvedContext = this . resolvedCtx ?? { } ) : string {
247- if ( mt . path . kind === 'literal' ) return String ( mt . path . raw ) ;
248- if ( mt . path . kind === 'interpolated' ) {
249- return interpolate ( mt . path . template , ctx ) ;
247+ try {
248+ if ( mt . path . kind === 'literal' ) return String ( mt . path . raw ) ;
249+ if ( mt . path . kind === 'interpolated' ) {
250+ return interpolate ( mt . path . template , ctx ) ;
251+ }
252+ // Branch value: dispatch then recursively resolve the chosen arm against ctx.
253+ const arm = resolveBranch ( mt . path , ctx as Record < string , string > ) as ResolvableValue ;
254+ if ( arm . kind === 'literal' ) return String ( arm . raw ) ;
255+ if ( arm . kind === 'interpolated' ) return interpolate ( arm . template , ctx ) ;
256+ // Nested branches are uncommon for modType paths but supported for symmetry.
257+ return String ( resolveBranch ( arm , ctx as Record < string , string > ) ) ;
258+ } catch {
259+ // Context not yet resolved (getPath called before discovery); return empty.
260+ return '' ;
250261 }
251- // Branch value: dispatch then recursively resolve the chosen arm against ctx.
252- const arm = resolveBranch ( mt . path , ctx as Record < string , string > ) as ResolvableValue ;
253- if ( arm . kind === 'literal' ) return String ( arm . raw ) ;
254- if ( arm . kind === 'interpolated' ) return interpolate ( arm . template , ctx ) ;
255- // Nested branches are uncommon for modType paths but supported for symmetry.
256- return String ( resolveBranch ( arm , ctx as Record < string , string > ) ) ;
257262 }
258263
259264 private async discover ( stores : StoreDecl [ ] ) : Promise < DiscoveryFacts | null > {
@@ -264,12 +269,32 @@ export class GdlRuntime {
264269 const found = await util . GameStoreHelper . findByAppId ( appIds ) ;
265270 if ( ! found ) return null ;
266271 this . discoveredStore = found . gameStoreId ;
272+ const os = process . platform === 'win32' ? 'windows' as const
273+ : process . platform === 'darwin' ? 'macos' as const
274+ : 'linux' as const ;
275+
276+ // Compute platform-specific AppData paths (Windows only for now).
277+ let appDataLocal : string | undefined ;
278+ let appDataLocalLow : string | undefined ;
279+ let appDataRoaming : string | undefined ;
280+ if ( os === 'windows' ) {
281+ const { homedir } = await import ( 'node:os' ) ;
282+ const { join, resolve } = await import ( 'node:path' ) ;
283+ const home = homedir ( ) ;
284+ appDataLocal = process . env . LOCALAPPDATA || join ( home , 'AppData' , 'Local' ) ;
285+ appDataLocalLow = resolve ( appDataLocal , '..' , 'LocalLow' ) ;
286+ appDataRoaming = process . env . APPDATA || join ( home , 'AppData' , 'Roaming' ) ;
287+ }
288+
267289 return {
268290 store : found . gameStoreId ,
269- os : process . platform === 'win32' ? 'windows' : process . platform === 'darwin' ? 'macos' : 'linux' ,
291+ os,
270292 arch : process . arch === 'arm64' ? 'arm64' : 'x64' ,
271293 installPath : found . gamePath ,
272294 executablePath : found . gamePath , // refined by Vortex later via game.executable()
295+ ...( appDataLocal !== undefined && { appDataLocal } ) ,
296+ ...( appDataLocalLow !== undefined && { appDataLocalLow } ) ,
297+ ...( appDataRoaming !== undefined && { appDataRoaming } ) ,
273298 } ;
274299 } catch {
275300 return null ;
0 commit comments