# AI_README.MD — Hasan Merkit GTA V SHVDN Project Rules
Generated for: GTA V Story Mode mod development
Last updated: 2026-06-23
Language rule: this document is written in English, and all source-code comments must also be written in English.
---
## 1. Purpose of This File
This file is the single source of truth for AI-assisted development of the Hasan Merkit GTA V Story Mode mod project.
It defines:
- The mandatory project structure.
- The two-mod architecture.
- The module-prefix system.
- The config layout.
- The debug behavior.
- The ScriptHookVDotNet compatibility rules.
- The ZIP delivery rules.
- The append-only module registry.
AI must read and follow this file before writing, editing, packaging, or explaining any project code.
---
## 2. Non-Negotiable Golden Rules
1. **Use ScriptHookVDotNet v3 only.**
- Reference `ScriptHookVDotNet3.dll`.
- Do not write new code against SHVDN v2 APIs.
- Raw `.cs` scripts are allowed in this project because the user requested `.cs` files, but code must still follow SHVDN v3 patterns.
2. **Stable-first compatibility is mandatory.**
- Code must compile against stable SHVDN `v3.6.0` unless the user explicitly approves a nightly-only experiment.
- Users may run a compatible Nightly runtime when newer GTA V builds require it.
- Do not use nightly-only APIs in production code.
3. **Direct `GTA.UI` usage is forbidden.**
- Do not use `using GTA.UI;`.
- Do not call `GTA.UI.Screen`, `GTA.UI.Notification`, `GTA.UI.Hud`, `GTA.UI.TextElement`, `GTA.UI.Sprite`, or similar APIs directly.
- Any screen text, menu, or debug display must go through a project-owned abstraction.
4. **Every feature must be modular.**
- Every module has one prefix.
- Every module has one config section.
- All variables and functions related to that module must use the module prefix.
5. **Every C# source file must use mandatory comment tags.**
- `// [F]` for functions and methods.
- `// [V]` for variables, fields, properties, and constants.
- `// [E]` for events, event handlers, and event subscriptions.
- `// [.]` for all other logic, steps, and notes.
- All source comments must be in English.
6. **The two project mods must not fight each other.**
- If one project mod opens its menu, the other project mod must close its menu.
- Modules inside the same mod must also avoid conflicts with each other.
7. **Respect other installed mods.**
- Do not permanently override weather, time, traffic, dispatch, player state, vehicle state, weapons, controls, radio, or world density unless the module explicitly owns that behavior and restores it safely.
- Do not spam natives every tick when state can be cached or throttled.
8. **Changed-files-only delivery is the default.**
- Unless the user says otherwise, every ZIP must include only changed files.
- Every ZIP filename must be unique.
9. **The only Markdown file is `AI_README.MD`.**
- Do not create `README.md`, `CHANGELOG.md`, `notes.md`, or any other `.md` file unless the user explicitly asks.
- If a Markdown file must be included in a ZIP, it must be this exact file: `AI_README.MD`.
10. **Every new module must be appended to the bottom of this file.**
- When a module is added, update the append-only module registry at the very bottom of this file.
- Do not remove or reorder previous module entries unless the user explicitly asks.
---
## 3. Required `scripts` Folder Structure
The user will extract delivery ZIP files directly inside the GTA V `scripts` folder.
Therefore, ZIP files must be designed with paths relative to the `scripts` folder root.
Correct ZIP root example:
```text
hasanmerkit_story.cs
hasanmerkit_story.modules/OnlineVehicles.cs
hasanmerkit_story.ini
hasanmerkit_hack.cs
hasanmerkit_hack.ini
AI_README.MD
```
Incorrect ZIP root examples:
```text
scripts/hasanmerkit_story.cs
scripts/hasanmerkit_story.ini
```
```text
HasanMerkitMod/hasanmerkit_story.cs
HasanMerkitMod/hasanmerkit_story.ini
```
Rules:
- Do not wrap files in an extra folder.
- Do not include unrelated files.
- Do not include unchanged files unless the user requests a full package.
- Do not include ScriptHookVDotNet files unless the user explicitly requests them and redistribution is appropriate.
- Do not include more than one Markdown file.
---
## 4. Project Mods
This project contains two independent SHVDN C# script mods.
### 4.1 Mod 1 — Hasan Merkit's Story Enhancer
- Display name: `Hasan Merkit's Story Enhancer`
- Core source file: `hasanmerkit_story.cs`
- Module source folder: `hasanmerkit_story.modules/`
- Config file: `hasanmerkit_story.ini`
- Purpose: Enhance GTA V Story Mode with optional, modular story-mode features.
- Current known module:
- `Online Vehicles in Story`
### 4.2 Mod 2 — Hasan Merkit's Hack Menu
- Display name: `Hasan Merkit's Hack Menu`
- Source file: `hasanmerkit_hack.cs`
- Config file: `hasanmerkit_hack.ini`
- Purpose: Provide a separate modular hack/menu feature set.
- Current known module:
- None yet.
### 4.3 Shared Project Rule
The two mods may coordinate menu ownership, but each mod must remain safe when the other mod is missing.
A project mod must never crash because the other project mod is not installed.
---
## 5. Config Architecture
Each mod owns its own config file.
### 5.1 Story Enhancer Config Base
File: `hasanmerkit_story.ini`
```ini
[General]
Enabled=1
Menu=F3
Debug=1
[OnlineVehicles]
Enabled=1
TrafficSpawn=1
ParkingSpawn=1
SuperOnly=0
SuperOnly_AllowPorAreas=0
```
### 5.2 Hack Menu Config Base
File: `hasanmerkit_hack.ini`
```ini
[General]
Enabled=1
Menu=F4
Debug=1
[Player]
Invincibility=0
NeverWanted=0
[GhostTown]
NoVehicles=0
NoPeople=0
NoAnimals=0
NoAmbient=0
```
### 5.3 General Section Rules
Every project config must include:
```ini
[General]
Enabled=1
Menu=F3
Debug=1
```
Meaning:
- `Enabled=1` means the mod is active.
- `Enabled=0` means the mod must load safely but skip feature execution.
- `Menu=F3` means the menu opens with `F3`.
- `Menu=` is valid and means the menu is disabled.
- A blank or invalid `Menu` value must never crash the script or corrupt the INI file.
- `Debug=1` means debug mode is active.
- `Debug=0` means debug output must be hidden or disabled.
### 5.4 Debug Mode Behavior
Debug mode must show module-related debug text on screen when appropriate.
Rules:
- Debug text must be useful for testing modules.
- Debug text must include the mod name or short mod prefix.
- Debug text must include the module prefix or module section name.
- Debug text must not be drawn in the lower-left radar area.
- Preferred debug overlay position is upper-right or another non-radar-safe area.
- Debug text content may be throttled/cached, but the overlay itself must draw every frame while visible to avoid flickering.
- Debug text must not use direct `GTA.UI` APIs.
- Feature modules must not draw text directly.
- Feature modules must send debug lines through a project-owned debug function.
- Story and Hack debug overlays may be visible at the same time.
- The two mods must use fixed stacked overlay positions so they never overlap each other, the radar, or the left-side menu.
- Do not use an exclusive shared debug owner slot that hides one mod's debug overlay while the other mod is active.
- A mod with no active runtime modules should not draw idle or empty debug text just because `Debug=1`.
Required pattern:
```csharp
// [F] Adds a debug line through the project-owned debug system.
private void coredebug_AddLine(string moduleName, string message)
{
// [.] Stop if debug mode is disabled.
if (!core_debug)
{
return;
}
// [.] Store or render the debug line through the approved project debug overlay.
}
```
Feature module usage:
```csharp
// [.] Report module status through the shared debug function.
coredebug_AddLine("OnlineVehicles", "Vehicle scan completed.");
```
---
## 6. Current Config State
### 6.1 `hasanmerkit_story.ini`
The current known Story Enhancer config must be:
```ini
[General]
Enabled=1
Menu=F3
Debug=1
[OnlineVehicles]
Enabled=1
SuperOnly=0
SuperOnly_AllowPorAreas=0
```
### 6.2 `hasanmerkit_hack.ini`
The current known Hack Menu config must be:
```ini
[General]
Enabled=1
Menu=F4
Debug=1
[Player]
Invincibility=0
NeverWanted=0
```
---
## 7. Module Architecture
### 7.1 Module Request Format
When the user requests a new module, the user may use this format:
```text
New Module (prefix_ [ConfigSection])
```
Example:
```text
New Module (onlinevehicles_ [OnlineVehicles])
```
This means:
- Module prefix: `onlinevehicles_`
- Config section: `[OnlineVehicles]`
- Every related variable must start with `onlinevehicles_`.
- Every related function must start with `onlinevehicles_`.
- Every related event handler must start with `onlinevehicles_`.
- Every related helper must start with `onlinevehicles_` unless it is a shared `core`, `coremenu`, `coredebug`, or `compat` helper.
- All config keys must be under `[OnlineVehicles]`.
### 7.2 Module Placement Rule
Modules may be split into separate source files when the feature is large enough to justify it. This is now the preferred structure for Story Enhancer modules.
Current Story Enhancer layout:
```text
hasanmerkit_story.cs
hasanmerkit_story.modules/OnlineVehicles.cs
```
Rules for separated module source files:
- The core mod file remains the only script entry point.
- A module source file must not inherit from `GTA.Script`.
- A module source file must not register its own `Tick`, `KeyDown`, `KeyUp`, or `Aborted` events directly.
- A module source file must be designed as part of the owning mod, not as an independently loadable script.
- For raw `.cs` delivery, separated module files should use the same partial class as the owning script when the runtime/compiler includes the file.
- If a user's SHVDN setup does not compile module subfolder source files, the package must be built as a compiled `.dll` or the module code must be merged back into the owning root `.cs` file for that delivery.
- The folder name must follow this pattern: `<owning_mod_file_without_ext>.modules/`.
Examples:
- Story Enhancer modules go inside `hasanmerkit_story.modules/`.
- Hack Menu modules will go inside `hasanmerkit_hack.modules/` when the first Hack module is added.
- `hasanmerkit_story.modules/OnlineVehicles.cs` is not a standalone script and must not be treated as a second mod.
### 7.3 Module Variable Rules
Correct:
```csharp
// [V] Stores whether the Online Vehicles module is enabled.
private bool onlinevehicles_enabled;
// [V] Stores whether only super vehicles should be allowed.
private bool onlinevehicles_superOnly;
```
Incorrect:
```csharp
private bool enabled;
private bool superOnly;
```
### 7.4 Module Function Rules
Correct:
```csharp
// [F] Loads Online Vehicles config values.
private void onlinevehicles_LoadConfig(ScriptSettings config)
{
// [.] Read whether the Online Vehicles module is enabled.
onlinevehicles_enabled = config.GetValue("OnlineVehicles", "Enabled", true);
}
```
Incorrect:
```csharp
private void LoadOnlineVehiclesConfig()
{
}
```
### 7.5 Module Config Rules
Correct:
```ini
[OnlineVehicles]
Enabled=1
SuperOnly=0
SuperOnly_AllowPorAreas=0
```
Incorrect:
```ini
[General]
OnlineVehiclesEnabled=1
OnlineVehiclesSuperOnly=0
```
---
## 8. Menu and Input Coexistence
### 8.1 Menu Ownership
Each mod must track whether its own menu is open.
```csharp
// [V] Stores whether the Story Enhancer menu is currently open.
private bool coremenu_isOpen;
```
When Story Enhancer opens its menu:
- Hack Menu must close its menu if it is open.
- Story Enhancer modules that own temporary input must pause or coordinate.
When Hack Menu opens its menu:
- Story Enhancer must close its menu if it is open.
- Hack Menu modules that own temporary input must pause or coordinate.
### 8.2 Safe Cross-Mod Coordination
Cross-mod menu coordination must be safe when only one mod is installed.
Rules:
- Do not hard-crash if the other mod is absent.
- Do not require both mods to be loaded.
- Use a minimal shared coordinator only if needed.
- The shared coordinator must not contain feature logic.
### 8.3 Input Rules
- Use key-down edge detection.
- One key press must trigger one action.
- Do not repeatedly toggle a value every tick while a key is held.
- Do not disable controls globally unless a menu or module requires it.
- Restore controls immediately when the menu or module closes.
### 8.4 Direct Module Menu Design
Project menus must not use a separate `Modules` list page.
Required Story Enhancer main page for the current build:
1. `Online Vehicles in Story`
2. `Debug`
Rules:
- Module entries must be listed directly on the first menu page.
- Selecting a module entry opens that module's settings page.
- A module entry on the first page must not directly toggle the module.
- The module settings page owns the module's config keys and live-save behavior.
- The current Story Enhancer module settings page must expose:
- `Enabled`
- `SuperOnly`
- `SuperOnly_AllowPorAreas`
- `Debug` may remain on the main page because it is a global setting.
- `Esc`, `Backspace`, or Left Arrow must return from child pages or close from the main page.
- `Enter` or Right Arrow may open a module settings page or toggle the selected setting.
- Menu drawing must go through native/project-owned drawing helpers and must not use direct `GTA.UI`.
- Menus must open on the upper-left side of the screen, away from the radar area.
- While a project menu is open, phone and common frontend controls must be disabled every frame so GTA's phone UI does not react behind the custom menu.
---
## 9. ScriptHookVDotNet Compatibility Rules
### 9.1 Build and Runtime Baseline
- Language: C#
- Runtime: .NET Framework 4.8+
- SHVDN API: v3
- Reference DLL: `ScriptHookVDotNet3.dll`
- Preferred compile/reference version: stable `v3.6.0`
### 9.2 Stable and Nightly Compatibility
The code must be compatible with:
- Stable SHVDN `v3.6.0` as the baseline API.
- SHVDN Nightly builds as runtime options for users with newer GTA V versions.
Rules:
- Do not use nightly-only APIs.
- Do not require a specific nightly build unless the user explicitly approves it.
- Do not rely on source-breaking nightly behavior.
- Do not mix `.asi` and `.dll` files from different SHVDN versions.
- If the user uses Nightly, they should use the `.ini`, `.asi`, and DLL files from the same Nightly package.
### 9.3 Known GTA V Version Compatibility Note
For GTA V `v1.0.3258.0` or later, users generally need `v3.6.0-nightly.89` or later because stable `v3.6.0` and `v3.5.1` have a known compatibility issue with those game versions.
Development rule:
- Build public code against stable `v3.6.0` APIs.
- Tell users to run a compatible Nightly runtime only when their GTA V build requires it.
### 9.4 Raw Script API Suffix Rule
If raw `.cs` scripts ever need explicit SHVDN API selection, use v3 suffix conventions where applicable.
However, the current requested source filenames are:
```text
hasanmerkit_story.cs
hasanmerkit_hack.cs
```
Do not rename them unless the user approves.
### 9.5 `NoScriptThread` Rule
Default rule:
- Do not set `NoScriptThread = true`.
If the user explicitly approves `NoScriptThread = true`:
- Do not call `Script.Yield()`.
- Do not call `Script.Wait()`.
- Do not call APIs that may internally wait for resources unless those resources are already loaded.
- Preload and validate models before spawning entities.
Safe model pattern:
```csharp
// [V] Store the requested vehicle model.
Model vehicleModel = new Model(VehicleHash.Sultan);
// [.] Request the model before creating the vehicle.
vehicleModel.Request(1000);
// [.] Stop if the model is invalid or not loaded.
if (!vehicleModel.IsValid || !vehicleModel.IsLoaded)
{
return;
}
// [V] Store the spawned vehicle after the model is loaded.
Vehicle spawnedVehicle = World.CreateVehicle(vehicleModel, spawnPosition);
// [.] Mark the model as no longer needed after use.
vehicleModel.MarkAsNoLongerNeeded();
```
### 9.6 Risky or Compatibility-Sensitive APIs
Avoid or handle carefully:
- `World.RaycastCapsule(...)`
- Treat as obsolete or risky for new code.
- Prefer `ShapeTest.StartTestCapsule(...)` and handle asynchronous results.
- `Ped.Weapon.Components`
- Access only after `ped != null`, `ped.Exists()`, and weapon validity checks.
- Do not poll heavily every tick.
- `World.CreateVehicle(...)`, `World.CreatePed(...)`, `World.CreateProp(...)`
- Always request and validate models first.
- Always release models after creation.
- Always clean up module-owned entities.
- Native enum values compiled as constants
- Do not copy old integer values for SHVDN enums.
- Use named enum values from the stable v3.6.0 reference.
- `Ped.AlwaysKeepTask`
- Do not assume it guarantees permanent task control by itself.
- Reapply or validate tasks safely when needed.
- SHVDN reload behavior
- Add cleanup in `Aborted` handlers.
- Reset static or shared state safely.
### 9.7 Direct `GTA.UI` Ban Details
Forbidden imports:
```csharp
using GTA.UI; // [.] Forbidden: do not use the GTA.UI namespace.
```
Forbidden usage:
```csharp
// [.] Forbidden: direct GTA.UI calls are not allowed in this project.
GTA.UI.Screen.ShowSubtitle("Debug text");
// [.] Forbidden: direct GTA.UI notifications are not allowed in this project.
GTA.UI.Notification.Show("Module enabled");
```
Allowed pattern:
```csharp
// [.] Allowed: report text through the project-owned debug gateway.
coredebug_AddLine("OnlineVehicles", "Module enabled.");
```
---
## 10. Required Comment Style
Every C# source file must use these tags.
```csharp
// [V] Stores whether the example module is enabled.
private bool example_enabled;
// [F] Toggles the example module state.
private void example_Toggle()
{
// [.] Flip the enabled flag.
example_enabled = !example_enabled;
}
// [E] Handles the script tick event.
private void example_OnTick(object sender, EventArgs e)
{
// [.] Skip work when the module is disabled.
if (!example_enabled)
{
return;
}
}
```
Rules:
- Comments must be short, useful, and in English.
- Do not write Turkish source-code comments.
- Every module-level variable must have a `// [V]` comment.
- Every method must have a `// [F]` comment.
- Every event subscription or handler must have a `// [E]` comment.
- Every meaningful operation block must have a `// [.]` comment.
---
## 11. Module Conflict Analysis Checklist
Before adding or changing any module, analyze:
1. Which mod owns this feature?
2. What is the module prefix?
3. What is the config section?
4. Which files change?
5. Does it use a key already used by another module?
6. Does it open or close a menu?
7. Does it use input while another module may use input?
8. Does it spawn vehicles, peds, props, blips, cameras, particles, sounds, markers, or checkpoints?
9. Does it modify player state, vehicle state, wanted level, weather, time, radio, HUD, dispatch, relationship groups, weapons, tasks, traffic, or world density?
10. Does it require cleanup when disabled, when the menu closes, when the script aborts, or when SHVDN reloads?
11. Does it use any forbidden `GTA.UI` API?
12. Does it compile against stable SHVDN `v3.6.0`?
13. Does it accidentally rely on a nightly-only API?
14. Does it respect the changed-files-only ZIP rule?
If there is a possible conflict, resolve it before coding.
---
## 12. Cleanup Rules
Every module must clean up its own temporary state.
Cleanup is required for:
- Spawned vehicles
- Spawned peds
- Spawned props
- Blips
- Cameras
- Particle effects
- Sounds
- Markers and checkpoints
- Relationship groups
- Disabled controls
- Modified player state
- Modified vehicle state
- Modified weather, time, traffic, dispatch, or world density
- Open menus
Required abort pattern:
```csharp
// [E] Handles script abort cleanup.
private void core_OnAborted(object sender, EventArgs e)
{
// [.] Close any open project menu.
coremenu_Close();
// [.] Clean up all module-owned temporary entities and state.
cleanup_AllModules();
}
```
Entity cleanup pattern:
```csharp
// [F] Deletes a module-owned vehicle safely.
private void onlinevehicles_DeleteVehicle(Vehicle vehicle)
{
// [.] Stop if the vehicle reference is missing or already deleted.
if (vehicle == null || !vehicle.Exists())
{
return;
}
// [.] Mark the vehicle as no longer persistent before deletion.
vehicle.IsPersistent = false;
// [.] Delete the module-owned vehicle.
vehicle.Delete();
}
```
---
## 13. Performance Rules
- Do not run expensive searches every tick.
- Cache module state.
- Use intervals for repeated scans.
- Check entity existence before native calls.
- Avoid creating new objects every frame.
- Avoid writing config every tick.
- Avoid logging every tick unless debug mode is enabled and throttled.
Tick throttle pattern:
```csharp
// [V] Stores the next game time when the module scan is allowed.
private int onlinevehicles_nextScanTime;
// [F] Runs the Online Vehicles scan at a safe interval.
private void onlinevehicles_TryScan()
{
// [.] Skip scanning until the throttle interval has passed.
if (Game.GameTime < onlinevehicles_nextScanTime)
{
return;
}
// [.] Schedule the next scan.
onlinevehicles_nextScanTime = Game.GameTime + 500;
// [.] Run the module scan logic here.
}
```
---
## 14. Logging and Debug Rules
Use project-owned debug and logging functions.
Rules:
- Debug output must depend on `[General] Debug`.
- Debug output must include module identity.
- Debug output content may be throttled, but visible debug overlays must draw every frame to avoid flickering.
- Debug overlays must avoid the lower-left radar area.
- Feature modules must not directly draw UI.
- Feature modules must not directly call `GTA.UI`.
Example:
```csharp
// [F] Writes a debug message when debug mode is enabled.
private void coredebug_Log(string moduleName, string message)
{
// [.] Stop if debug logging is disabled.
if (!core_debug)
{
return;
}
// [.] Write the debug message with a project prefix.
Logger.Log($"[HasanMerkit][{moduleName}] {message}");
}
```
---
## 15. ZIP Delivery Rules
Unless the user asks otherwise:
- Deliver only changed files.
- Put changed files in a ZIP.
- Every ZIP filename must be unique.
- ZIP contents must be relative to the GTA V `scripts` folder root.
- The user must be able to extract the ZIP directly inside `scripts`.
- Do not include a parent `scripts` folder inside the ZIP.
- Do not include an extra project wrapper folder inside the ZIP.
- Include only one Markdown file, and it must be named `AI_README.MD`.
Recommended ZIP naming:
```text
HasanMerkit_GTA5_ChangedFiles_YYYYMMDD_HHMMSS.zip
```
Example changed-files ZIP for the current Story Enhancer update:
```text
hasanmerkit_story.cs
hasanmerkit_story.ini
AI_README.MD
```
---
## 16. Information Collection Rules Before Coding
If mod or module information is missing, collect it after the structure rules are understood.
Ask only for missing decisions that are required to design safely.
Useful questions:
1. Which mod owns the feature?
2. What is the module name?
3. What is the module prefix?
4. What is the config section?
5. What config keys are required?
6. What should the feature do?
7. What should the feature never do?
8. Which menu key or toggle key should be used?
9. Should the delivery include source code only, compiled DLL only, or both?
Do not ask for information that has already been provided.
---
## 17. Research Notes and Source-Aware Rules
These compatibility-sensitive facts were reviewed for this project:
- SHVDN is a runtime under Script Hook V for GTA V Story Mode scripts written in .NET languages.
- SHVDN requires Script Hook V, .NET Framework 4.8+, and the supported Microsoft Visual C++ Redistributable.
- Stable SHVDN `v3.6.0` is the stable baseline selected for this project.
- For GTA V `v1.0.3258.0` or later, stable `v3.6.0` and `v3.5.1` have a known compatibility issue that can crash the game when opening the SHVDN console or using instant reload.
- Users on affected GTA V versions should generally run `v3.6.0-nightly.89` or later.
- Developers should build public scripts against stable versions instead of nightly-only APIs.
- Nightly releases can include source-breaking changes for nightly-only APIs.
- Nightly releases changed raw script default API behavior from v2 to v3, so raw scripts should use explicit API suffixes when applicable.
- Nightly `.ini` settings changed; users should use the `.ini` that comes with the nightly release.
- Updating SHVDN should update the `.asi` and both API DLL files together.
- SHVDN `v3.6.0` added `ShapeTest` and marked `World.RaycastCapsule()` obsolete because capsule shape tests are asynchronous.
- SHVDN `v3.6.0` notes mention `NoScriptThread`; when enabled, `Script.Yield()` and `Script.Wait()` are unavailable and throw exceptions.
- SHVDN `v3.6.0` notes mention enum/native hash updates; avoid old hardcoded enum integers and compile against the correct stable reference.
- `GTA.UI` exists in SHVDN v3 documentation, but this project bans direct `GTA.UI` usage to avoid UI compatibility and namespace-change risks.
Reviewed reference URLs:
- https://github.com/scripthookvdotnet/scripthookvdotnet
- https://github.com/scripthookvdotnet/scripthookvdotnet/releases
- https://github.com/scripthookvdotnet/scripthookvdotnet-nightly
- https://github.com/scripthookvdotnet/scripthookvdotnet-nightly/releases
- https://scripthookvdotnet.github.io/
- https://nitanmarcel.github.io/scripthookvdotnet/scripting_v3/GTA.UI.html
- https://nitanmarcel.github.io/scripthookvdotnet/scripting_v3/GTA.UI.Notification.html
- https://nitanmarcel.github.io/scripthookvdotnet/scripting_v3/GTA.UI.Screen.ShowSubtitle.html
- https://www.dev-c.com/gtav/scripthookv/
---
## 18. Current Project Snapshot
### 18.1 Known Mods
1. `Hasan Merkit's Story Enhancer`
- Core source: `hasanmerkit_story.cs`
- Module source folder: `hasanmerkit_story.modules/`
- Current module placeholder: `hasanmerkit_story.modules/OnlineVehicles.cs`
- Runtime module implementation for raw `.cs` delivery: merged inside `hasanmerkit_story.cs`
- Config: `hasanmerkit_story.ini`
- Base config section: `[General]`
2. `Hasan Merkit's Hack Menu`
- Source: `hasanmerkit_hack.cs`
- Runtime module implementation for raw `.cs` delivery: merged inside `hasanmerkit_hack.cs`
- Current modules: `Player`, `Ghost Town`
- Config: `hasanmerkit_hack.ini`
- Base config section: `[General]`
### 18.2 Known Config Files
`hasanmerkit_story.ini`:
```ini
[General]
Enabled=1
Menu=F3
Debug=1
[OnlineVehicles]
Enabled=1
TrafficSpawn=1
ParkingSpawn=1
SuperOnly=0
SuperOnly_AllowPorAreas=0
```
`hasanmerkit_hack.ini`:
```ini
[General]
Enabled=1
Menu=F4
Debug=1
[Player]
Invincibility=0
NeverWanted=0
[GhostTown]
NoVehicles=0
NoPeople=0
NoAnimals=0
NoAmbient=0
```
`hasanmerkit_story.onlinevehicles.parkingpoints.ini`:
```ini
# Hasan Merkit Story Enhancer - Online Vehicles parking points
# Format: x,y,z,heading,zoneCode,areaTier
[ParkingPoints]
```
---
## 19. Append-Only Module Registry
Every time a new module is added, append a new entry to the bottom of this section.
Do not remove, reorder, or rewrite existing entries unless the user explicitly asks.
### 19.1 Module: Online Vehicles in Story
- Added: 2026-06-23
- Owning mod: `Hasan Merkit's Story Enhancer`
- Core source file: `hasanmerkit_story.cs`
- Module placeholder file: `hasanmerkit_story.modules/OnlineVehicles.cs`
- Runtime implementation location for raw `.cs` ZIP builds: inside `hasanmerkit_story.cs`
- Config file: `hasanmerkit_story.ini`
- Module display name: `Online Vehicles in Story`
- Module prefix: `onlinevehicles_`
- Config section: `[OnlineVehicles]`
- Current config keys:
- `Enabled=1`
- `TrafficSpawn=1`
- `ParkingSpawn=1`
- `SuperOnly=0`
- `SuperOnly_AllowPorAreas=0`
- Required config block:
```ini
[OnlineVehicles]
Enabled=1
TrafficSpawn=1
ParkingSpawn=1
SuperOnly=0
SuperOnly_AllowPorAreas=0
```
- Notes:
- This module belongs only to Story Enhancer.
- All related variables and functions must start with `onlinevehicles_`.
- It must respect `[General] Enabled` and `[General] Debug`.
- It must send debug text through the project-owned debug system.
- It must not directly use `GTA.UI`.
- It must target vehicles that Story Mode ambient traffic does not normally spawn, eventually covering the A-to-Z online/non-story vehicle pool.
- When debug is enabled, vehicles spawned by this module must be tracked with a radar blip using a vehicle-style icon.
- When debug is disabled, module-owned debug blips must be removed or hidden safely.
- Blips must be attached only to vehicles spawned by this module, not to vanilla traffic or vehicles from other mods.
- Parking spawn points must be stored in `hasanmerkit_story.onlinevehicles.parkingpoints.ini`, not in the main config and not in this README.
- When Story Debug is enabled, the Online Vehicles settings page may show `[Debug] Add Spawn Point` above normal settings.
- If the player steals or starts using a module-spawned vehicle, remove it from OnlineVehicles tracking and delete its debug blip; the game must be allowed to keep that vehicle normally.
### 19.2 Module: Player
- Added: 2026-06-23
- Owning mod: `Hasan Merkit's Hack Menu`
- Runtime implementation location for raw `.cs` ZIP builds: inside `hasanmerkit_hack.cs`
- Config file: `hasanmerkit_hack.ini`
- Module display name: `Player`
- Module prefix: `_player`
- Config section: `[Player]`
- Current config keys:
- `Invincibility=0`
- `NeverWanted=0`
- Required config block:
```ini
[Player]
Invincibility=0
NeverWanted=0
```
- Notes:
- This module belongs only to Hack Menu.
- All related variables and functions should start with `_player` for this module because the user requested `Player (_player)`.
- `Heal Player` is an action and must not be stored in the config.
- `Invincibility` is the English label for the Turkish "Ölümsüzlük" option and must be saved to config.
- `Wanted Level` must always display the current game wanted level and support left/right adjustment in the normal `0..5` range.
- `Wanted Level: Set Never Wanted` must be a tick-style config option and must force wanted level back to `0` while enabled.
- Hack Menu uses a red visual theme so it is visually distinct from Story Enhancer.
- The module must not directly use `GTA.UI`.
### 19.3 Module: Ghost Town
- Added: 2026-06-25
- Owning mod: `Hasan Merkit's Hack Menu`
- Runtime implementation location for raw `.cs` ZIP builds: inside `hasanmerkit_hack.cs`
- Config file: `hasanmerkit_hack.ini`
- Module display name: `Ghost Town`
- Module prefix: `ghosttown_`
- Config section: `[GhostTown]`
- Current config keys:
- `NoVehicles=0`
- `NoPeople=0`
- `NoAnimals=0`
- `NoAmbient=0`
- Required config block:
```ini
[GhostTown]
NoVehicles=0
NoPeople=0
NoAnimals=0
NoAmbient=0
```
- Notes:
- `No Vehicles` suppresses vehicle density and deletes nearby non-player, non-mission vehicles.
- `No People` removes ambient human peds but must preserve peds inside traffic vehicles.
- `No Animals` removes non-human peds only.
- `No Ambient` is a best-effort audio suppression feature and must restore audio state when disabled or when the script aborts.
- While `No Vehicles` is active, the Hack Menu must publish `HasanMerkit.GhostTown.NoVehicles=1` through AppDomain so Story OnlineVehicles can pause new spawns.
### 19.4 Module: Vehicles
- Added: 2026-06-25
- Owning mod: `Hasan Merkit's Hack Menu`
- Runtime implementation location for raw `.cs` ZIP builds: inside `hasanmerkit_hack.cs`
- Config file: `hasanmerkit_hack.ini`
- Extra data file: `hasanmerkit_hack.vehicles.saved.ini`
- Module display name: `Vehicles`
- Module prefix: `vehicles_`
- Config section: `[Vehicles]`
- Current config keys:
- `VehicleInvincibility=0`
- Required config block:
```ini
[Vehicles]
VehicleInvincibility=0
```
- Notes:
- `Saved Vehicles` is a child menu inside this module.
- Saved vehicles must be stored outside the main config in `hasanmerkit_hack.vehicles.saved.ini`.
- `Save Current Vehicle` is an action and must not be stored as a config key.
- Saved vehicle rows should spawn the selected saved vehicle near the player.
- `Rename a Saved Vehicle` and `Delete a Saved Vehicle` must operate on the selected saved row.
- `Vehicle Invincibility` is a config-backed toggle and must continuously reinforce the current player vehicle while enabled.
- `Modifications` is a placeholder page and must show `Coming Soon!` until the user designs it.
- The module must not directly use `GTA.UI`.
---
## 20. Latest Implementation Notes
### 20.1 2026-06-23 Menu and Debug Revision
- Main menu is now direct-module based: module entries appear on the first page with `Debug`.
- The separate `Modules` page has been removed.
- Story Enhancer currently has `Main > Online Vehicles` with `Enabled`, `SuperOnly`, and `SuperOnly_AllowPorAreas`.
- Story Enhancer menu opens on the upper-left side of the screen.
- Menu-open frames must suppress phone and common frontend controls.
- Debug overlay must not be placed over the radar.
- Debug overlay content may be cached/throttled, but the overlay must draw every frame while enabled to prevent flicker.
- Story and Hack debug overlays may draw at the same time. They must use fixed non-overlapping screen slots instead of a shared exclusive owner slot.
- Hack Menu must not draw idle debug text when it has no runtime modules and no open menu.
- Spawned Online Vehicles must get debug radar blips when `[General] Debug=1`.
- Online Vehicles debug blips must be removed when debug mode is turned off or when vehicles disappear.
- Debug blips must be owned and cleaned by the module that created them.
### 20.2 2026-06-23 Module Split Revision
- Initial attempt: `Online Vehicles in Story` was moved into `hasanmerkit_story.modules/OnlineVehicles.cs` as a partial class.
- Result: this is unsafe for raw SHVDN `.cs` distribution because SHVDN may compile every `.cs` file under `scripts` as a separate source file.
- `hasanmerkit_story.cs` remains the core entry script and owns SHVDN events.
- A module file must not depend on private helpers from the core script unless a real C# project/DLL build compiles all source files together.
- For direct-to-`scripts` ZIP releases, runtime module code must be merged into the owner script file or shipped in a non-compiled extension.
- `hasanmerkit_story.modules/OnlineVehicles.cs` is kept only as a compile-safe placeholder/source guard so older broken extracts are overwritten.
- ZIP delivery must preserve the `hasanmerkit_story.modules/` folder path relative to the `scripts` root when placeholder/source files are included.
### 20.3 2026-06-23 Compile Log Correction
User compile log showed these errors after the first module split package:
- `hasanmerkit_story.cs` could not find `onlinevehicles_*` functions because `OnlineVehicles.cs` was compiled as a separate file instead of being compiled together with the partial core class.
- `OnlineVehicles.cs` could not find `core_*` variables and helpers for the same reason.
- `Entity.FromHandle` must not be used in this raw-script code path; track spawned `Vehicle` references directly instead.
- `Blip.Delete()` is valid in SHVDN v3 docs, but fallback v2 compilation can complain. The real fix is to make the v3 compile succeed and avoid fallback.
- `GetRelativeFilePath` and some text-command native enum names can also appear as errors only during fallback to API v2. Do not chase those fallback errors until all v3 compile errors are fixed.
- Never assume subfolder `.cs` files are ignored by SHVDN. The log proved that `hasanmerkit_story.modules/OnlineVehicles.cs` was discovered and compiled.
- For raw `.cs` releases, avoid C# `partial` module splitting across separate files. Use one of these safe patterns:
1. merge runtime module code into the owner script file,
2. ship module notes/templates with a non-compiled extension, or
3. build a DLL from a real C# project where all `.cs` files are compiled into the same assembly.
- The current quick-fix uses pattern 1 for runtime code and keeps `hasanmerkit_story.modules/OnlineVehicles.cs` as a harmless placeholder that does not inherit `GTA.Script`.
Future AI must read the compile log before changing architecture. If the user will unzip directly into `scripts`, every `.cs` inside that tree must compile by itself or must be removed/renamed to a non-compiled extension.
### 20.4 2026-06-23 Modern Menu, Debug, Spawn, and Player Module Revision
- The user provided an old trainer-style screenshot as visual inspiration; future menus should keep the new wide, dark, left-side panel style with a header, accent bar, key badge, page title, page counter, row highlight, and compact footer help.
- Story Enhancer must use the cyan/blue accent theme.
- Hack Menu must use the red accent theme.
- Module entries must appear directly on the first menu page; do not reintroduce a separate `Modules` submenu unless the user explicitly asks.
- A module row opens that module's settings page; it must not directly toggle the module from the main page.
- Debug text for Story Enhancer must be module-focused and use this structure for Online Vehicles:
```text
[Online Vehicles]
Spawned Car Count: <number>
Current Area: <readable area name> (<tier>)
```
- Do not draw core/internal debug noise such as menu page, owner slot, or raw config booleans unless the user asks for low-level diagnostics.
- The previous Online Vehicles foundation only had blip tracking and did not actually spawn vehicles; this is why the user saw no radar debug blips.
- Online Vehicles now needs an actual lightweight spawn injector before debug blips can appear.
- Debug blips must be created only for vehicles spawned by `onlinevehicles_` logic and must be removed when debug is turned off or the vehicle becomes invalid/far away.
- Current-area detection should use GTA zone code -> readable name -> tier mapping, and the debug tier must be clear, e.g. `RICH`, `POOR`, `INDUSTRIAL`, `RURAL`, or `MIXED`.
- `SuperOnly=1` must restrict the selected model pool to high-end/super vehicles.
- `SuperOnly_AllowPorAreas=0` must prevent super-only spawns in `POOR`, `INDUSTRIAL`, and `RURAL` tiers. Keep the exact misspelled key name `SuperOnly_AllowPorAreas` for config compatibility.
- The online vehicle pool should be model-name based and must validate `Model.IsInCdImage`, `Model.IsVehicle`, and `Model.IsLoaded` before spawning, because different GTA V builds may not contain every DLC model.
- Use small, timed spawn attempts and a max tracked nearby count; never spawn vehicles every frame.
- Hack Menu now has the first module `Player (_player)` with `Heal Player`, `Invincibility`, `Wanted Level`, and `Wanted Level: Set Never Wanted`.
- `Invincibility` and `NeverWanted` are saved live to `[Player]`; `Heal Player` and current wanted level are not saved.
- Manual wanted-level adjustment should not navigate back. If `NeverWanted` is enabled, the level may snap back to 0 until the user turns `NeverWanted` off.
- Continue to use `ScriptSettings.Save()` first and the manual UTF-8 fallback writer second for live INI changes.
- Every new module still requires a new append-only registry entry at the bottom of section 19.
### 20.5 2026-06-24 Compile and Menu Input Correction
- User compile log showed `Vector3` missing in `hasanmerkit_story.cs` at `core_GetDistance(Vector3 a, Vector3 b)`. Future AI must add `using GTA.Math;` whenever raw `.cs` code uses `Vector3`, or fully qualify it as `GTA.Math.Vector3`. Do not assume `using GTA;` imports math types.
- Fix v3 compile errors first and ignore fallback v2 noise until the v3 compile is clean. In this case the fallback log was not the root issue; the missing `GTA.Math` import was.
- Do not ship a Story Enhancer build that uses `Vector3` without `using GTA.Math;`; this caused the whole Story module to fail while Hack still loaded.
- Menu selected-row text must not look bold/heavy. Native `SET_TEXT_OUTLINE` makes dark selected-row text appear too thick on bright highlight strips, so avoid outline on menu row text unless a separate non-selected/debug-only text helper is introduced.
- Left and Right keys must be treated as adjustment keys, not as navigation-back shortcuts. `Left` must never return to the previous page from an adjustable module page. Use `ESC` or `Backspace` only for Back/Close behavior.
- For Hack `Player` settings, `Left` on `Wanted Level` must decrease the wanted level, and `Right` must increase it. `Left` on toggle rows may toggle or do nothing, but it must not leave the Player page.
- For Story `Online Vehicles` settings, `Left`, `Right`, and `Enter` may toggle boolean rows, but only `ESC`/`Backspace` may return to the main page.
- When a user reports that a menu key caused an unexpected page change, inspect the input-routing function before changing feature logic. The bug is usually key routing, not the module itself.
### 20.6 2026-06-25 Pretty Settings and Traffic-Lane Spawn Correction
- Menu rows shown to the user must use readable UI labels, not raw INI key names. Keep raw names such as `SuperOnly` and `SuperOnly_AllowPorAreas` only inside config read/write code and internal comments.
- For `Online Vehicles`, use labels like `Module Enabled`, `Super Cars Only`, and `Allow Super Cars In Poor Areas` in the menu. Do not expose `Enabled`, `SuperOnly`, or `SuperOnly_AllowPorAreas` as visible menu text unless the user explicitly asks for raw config mode.
- `Online Vehicles` must inject cars as road traffic, not as random world props. Do not choose a random open-world point and simply call `World.CreateVehicle` with the player's heading.
- Traffic spawning must first ask GTA pathing for a valid vehicle node and heading, preferably through `GET_CLOSEST_VEHICLE_NODE_WITH_HEADING` with `OutputArgument` values. Validate with `IS_POINT_ON_ROAD` before creating the vehicle.
- A spawned online vehicle should receive an ambient driver and a driving task, e.g. `CREATE_RANDOM_PED_AS_DRIVER`, `SET_PED_KEEP_TASK`, and `TASK_VEHICLE_DRIVE_WANDER`, so it merges into traffic instead of sitting at the roadside.
- Do not stack OnlineVehicles cars on top of each other. Check tracked module-owned vehicles near the candidate node before spawning.
- Keep the spawn point outside the player's immediate interaction bubble. Current rule: reject traffic nodes too close to the player and too far from the active streaming area.
- If no safe road node is found, skip that spawn attempt silently and wait for the next interval; never fall back to sidewalk/random placement.
- Future AI should preserve this traffic-lane approach when expanding the A-Z online vehicle pool. The main quality bar is: the player should encounter the new cars as moving traffic, not as random parked or misplaced cars.
### 20.7 2026-06-25 Uploaded Mod Analysis and Traffic-Replacement Correction
- The user uploaded `All-MP-Vehicles-in-SP-3.0.7.zip` as inspiration. The archive contains a compiled DLL and PDB, but no source code. Future AI must not claim to have read its internal source unless a real decompiler/source file is available.
- Safe analysis from the uploaded README/config/list files:
- The reference mod adds GTA Online vehicles into SP traffic and parking lots.
- It exposes `spawn_traffic`, `traffic_cars_blips`, `time_traffic_gen`, `SpawnDistance`, and `DespawnDistance` settings.
- It supports a blacklist file and an add-on vehicle list where every custom model must include a vehicle class.
- It describes class/location-aware spawning: each vehicle class appears only on suitable roads/sections, and specialized vehicles use lore-appropriate places.
- User correction: `Online Vehicles` must be based on GTA's existing traffic, not only GTA vehicle nodes. Do not create online cars from arbitrary sampled vehicle nodes and hope they merge into traffic.
- New implementation rule: choose a real ambient traffic vehicle created by GTA, validate that it is a road vehicle with a non-player driver, capture its position/heading/speed, delete or replace that traffic car, then create the online vehicle at the same traffic-derived slot.
- This traffic-replacement approach should make spawned online vehicles appear as part of the live traffic stream instead of appearing at random roadside/node locations.
- Never replace the player's current vehicle, a vehicle already tracked by `onlinevehicles_`, police/emergency/military/commercial/service-style classes, airborne vehicles, vehicles without a driver, or vehicles too close to the player.
- Keep debug blips attached only to vehicles created by `onlinevehicles_`, not to the original GTA traffic vehicles.
- If no valid ambient traffic vehicle exists near the player, skip the spawn attempt. Do not fall back to random world placement.
- Future class-aware expansion should follow the reference mod's idea: map online vehicle candidates by class and area/road context. The menu should keep friendly labels while config retains raw keys.
### 20.8 2026-06-25 Area Quality Pools and Simultaneous Debug Revision
- User requested `Bölgeye göre araç kalitesi`; `Online Vehicles` must select online replacement cars from area-quality pools, not from one flat random list.
- Required area-quality behavior:
- `RICH`: premium sports, super, luxury sedan/SUV, and sports classics.
- `MIXED`: balanced sports, sedan, SUV, compact, muscle, and mid-tier online cars.
- `POOR`: cheaper, older, compact, bike, older muscle, and rougher cars.
- `INDUSTRIAL`: utility, pickup, off-road, work-style, and rough vehicles.
- `RURAL`: off-road, pickup, bike, and countryside-friendly vehicles.
- `SuperOnly=1` must override the area pool and use only the high-end/super pool, but `SuperOnly_AllowPorAreas=0` still blocks super-only replacement in `POOR`, `INDUSTRIAL`, and `RURAL` tiers.
- Keep the traffic-replacement rule from 20.7: pick a real GTA ambient traffic vehicle, capture its road slot, then replace it with an area-appropriate online vehicle. Do not return to node-only spawning.
- Story and Hack debug overlays must be allowed to run together. Do not use an exclusive shared debug owner slot that prevents one mod from drawing while the other has debug enabled. Use fixed stacked positions instead.
- Current layout rule: Story/OnlineVehicles debug draws in the upper-right stack; Hack/Player debug draws directly below it. Both must avoid the radar and the left menu.
- Debug overlay style should match the menu style: dark translucent card, small accent bar, readable title, stable cached text, and no flicker.
- Menu style should be the newer compact left-side glass/card design with module rows on the first page, accent colors per mod, a key badge, page counter, thin selected-row accent, and non-bold selected text.
- Story Enhancer keeps the cyan/blue theme. Hack Menu keeps the red theme.
- Future AI must avoid contradictory debug rules: older notes about only one debug overlay were superseded by this simultaneous-debug requirement.
### 20.9 2026-06-25 Parking Points, Stolen Vehicles, Ghost Town, and DLC Pool Expansion
- User requested that stolen OnlineVehicles cars must be left to the game. Future AI must remove player-used module cars from `onlinevehicles_` tracking, delete only the module debug blip, and avoid deleting or continuing to manage that vehicle. This helps reduce ownership/save conflicts.
- OnlineVehicles must pause new traffic and parking spawn attempts during cutscenes and GTA character switching. Debug must expose the current blocker as `Temporary Disabled: No`, `Temporary Disabled: Yes for Character Switch`, `Temporary Disabled: Yes for Cutscene`, or another explicit project blocker such as `Yes for Ghost Town`.
- Ghost Town `No Vehicles` must also pause Story OnlineVehicles through a shared AppDomain flag. Do not let Story immediately create new cars while Hack is intentionally clearing/suppressing vehicles.
- Parking spawn points are now a separate runtime data file: `hasanmerkit_story.onlinevehicles.parkingpoints.ini`. They must be written with `CultureInfo.InvariantCulture` so Turkish/Windows decimal separators do not corrupt coordinates.
- The debug-only menu row `[Debug] Add Spawn Point` appears only when Story Debug is enabled and must be rendered as a friendly action row, not as a raw config key.
- Parked online vehicles may spawn only from saved points, with distance checks and nearby-vehicle checks. They must not appear randomly on sidewalks or arbitrary nodes.
- Ghost Town cleanup must skip the player, the player's vehicle, mission/special entities, and traffic drivers/passengers. `No People` should not empty drivers from live traffic vehicles.
- `No Ambient` is build-dependent and best-effort. Always restore any audio scene/flag when disabled or on script abort, and keep failures inside `try/catch`.
- The online vehicle pools were expanded with newer DLC model IDs from the latest GTA Online vehicle lists, but every model must still be validated with `Model.IsInCdImage`, `Model.IsVehicle`, and `Model.IsLoaded` before use because Legacy/Enhanced/game-build coverage differs.
- GTABase currently lists the GTA V/GTA Online database as updated through June 2026, and Story Mode stopped receiving new vehicles after the July 8, 2015 Ill-Gotten Gains Part 2 update. Therefore this module should treat later vehicles as Online-only candidates and validate them at runtime.
### 20.10 2026-06-25 OnlineVehicles Cleanup, Non-Rich Super Rule, Ghost Town Diagnostics, and Vehicles Module
- The Online Vehicles module menu must put `Module Enabled` at the very top of its module settings page. Debug-only action rows such as `[Debug] Add Spawn Point` must appear below the master switch, not above it.
- Add a friendly action row named `Clear Spawned Vehicles` at the bottom of the Online Vehicles settings page. It must delete only vehicles currently tracked by `onlinevehicles_` and must preserve the player's current vehicle by releasing it from module ownership instead of deleting it.
- When `Module Enabled` is turned from ON to OFF, Online Vehicles must perform one cleanup pass by calling the same tracked-vehicle cleanup logic. Do not leave managed debug-blip/tracked vehicles behind after the module is disabled.
- Rename the visible menu label from `Allow Super Cars In Poor Areas` to `Allow Super Cars In Non-Rich Areas`. The old label was too narrow because the rule also affects mixed, industrial, and rural areas.
- The new primary config key is `SuperOnly_AllowNonRichAreas`. For backward compatibility, read the old misspelled `SuperOnly_AllowPorAreas` key as a fallback when the new key does not exist. Future manual writers should output only the new key unless the user asks for legacy compatibility in the file itself.
- `Allow Super Cars In Non-Rich Areas` matters only while `Super Cars Only` is ON. If `Super Cars Only` is OFF, show this menu row as `DISABLED` and ignore input on it. Do not let this option affect normal area-quality pools.
- The non-rich super restriction must block all tiers other than `RICH` when `Super Cars Only=1` and `SuperOnly_AllowNonRichAreas=0`. This includes `MIXED`, `POOR`, `INDUSTRIAL`, and `RURAL`, not only low-income zones.
- Apply the same non-rich super restriction to parked spawn points. If a saved point is non-rich and non-rich super permission is disabled, skip that parked spawn attempt.
- Rare vehicles that remain visible while Hack `Ghost Town > No Vehicles` is enabled are usually one of these: mission/script-owned vehicles, special scenario entities, vehicles outside the current scan radius at the moment of cleanup, streamed entities created after the last cleanup tick, trains/boats/special generators, or entities the game marks as protected. Do not assume they are OnlineVehicles cars unless they are tracked by `onlinevehicles_`.
- Ghost Town must expose diagnostics for rare leftover vehicles. Track per-cleanup counters such as scanned vehicles, deleted vehicles, skipped player vehicle, and skipped mission/special vehicles. Debug should show a compact line such as `Vehicles ON | Del X/Y | Special Z` so the next AI can see whether leftovers are protected rather than missed.
- Ghost Town `No Vehicles` should use multiple layers: per-frame density multipliers, garbage/boat/train suppression where available, and periodic nearby entity deletion. Keep mission/special entities skipped for safety unless the user explicitly asks for a dangerous aggressive mode.
- Add Hack module `Vehicles (vehicles_ [Vehicles])` with a red-theme module page. It must contain `Saved Vehicles`, `Vehicle Invincibility`, and `Modifications`.
- `Saved Vehicles` is a child page with `Save Current Vehicle`, saved vehicle rows, `Rename a Saved Vehicle`, and `Delete a Saved Vehicle`. The saved data lives in `hasanmerkit_hack.vehicles.saved.ini`, separate from the main Hack config.
- Saved vehicle storage currently uses `name|modelHash` lines so online/add-on vehicles can be respawned by model hash without needing fragile display-name-to-model conversion. Future improvements may add colors, livery, mods, dirt, health, and extras after the Modifications feature is designed.
- Avoid native text input or `GTA.UI` input helpers for rename until a stable project-owned text input method is designed. Current rename behavior may use a safe preset-style name. If the user wants true typed renaming, design a custom keyboard capture flow or a documented native onscreen-keyboard wrapper and test it against SHVDN stable/nightly.
- `Vehicle Invincibility` is saved to `[Vehicles] VehicleInvincibility`. When enabled, repair/clean the current vehicle once, then continuously protect the current vehicle with native calls: entity invincible, no visible damage, non-burst tires, non-breaking wheels, strong vehicle flag, full engine/body/petrol health, zero dirt, and window repair where supported.
- While Vehicle Invincibility is active, keep the player's current vehicle reinforced every tick because GTA may reset some damage flags after collisions, weapon hits, or vehicle changes. When disabled, restore common protection flags on the current vehicle when possible.
- The Vehicles module `Modifications` page is intentionally a placeholder that shows `Coming Soon!`; do not implement tuning/mod kits until the user explicitly designs that feature.
### 20.11 2026-06-25 Saved Vehicle UX Fixes, Menu Overflow Guard, and Temporary Sound Debug
- Menu rows must never draw unbounded native text. GTA native text has no panel clipping, so long titles/values/notes can spill outside the menu. Every row title and value should be passed through a small fit/truncate helper before drawing.
- Action rows that run on Enter and have no persistent value must not show fake value labels such as `RUN`. Keep the value column blank for actions like `Heal Player`, `Save Current Vehicle`, `Refresh Nearby Sound Scan`, and similar one-shot commands.
- `Rename a Saved Vehicle` and `Delete a Saved Vehicle` must not operate on the last spawned/selected saved vehicle implicitly. They must open a target selection page so the user explicitly chooses which saved vehicle will be renamed or deleted.
- Typed saved-vehicle rename is now allowed through a project-owned native on-screen keyboard wrapper, not through `GTA.UI`. Use direct native hashes for `DISPLAY_ONSCREEN_KEYBOARD`, `UPDATE_ONSCREEN_KEYBOARD`, and `GET_ONSCREEN_KEYBOARD_RESULT` to avoid missing enum members across SHVDN stable/nightly/fallback behavior. Keep all keyboard state in the Vehicles module and ignore menu navigation while text input is active.
- Saved vehicle names from user input must be sanitized before writing to `hasanmerkit_hack.vehicles.saved.ini`: remove pipe delimiters, remove line breaks, trim whitespace, reject blank names, and limit length so menu rows stay readable.
- The previous preset-style rename behavior is superseded. Future AI should preserve the explicit target list + typed rename flow unless the user asks for a simpler preset rename mode.
- A temporary Hack module `Sound Debug (sounddebug_ [SoundDebug])` was added to help improve `Ghost Town > No Ambient`. It is intentionally diagnostic, not a finished gameplay feature.
- Important limitation: SHVDN/GTA script access does not expose a reliable complete live list of every audio stream the player hears. `Sound Debug` should therefore list nearby likely-audible candidates such as vehicles, peds, animals, and close active vehicles. Do not claim it can see the internal GTA audio mixer/bus unless a proven native/source confirms that capability.
- Sound Debug config lives in `[SoundDebug] Enabled=0`. The menu row is `Sound Debug`; its page contains `Module Enabled` and `Refresh Nearby Sound Scan`.
- Sound Debug output can be shown inside its menu and, when enabled, in the Hack debug stack. Keep it compact so it does not cover the menu, radar, or Story debug card.
- These changes were prompted by a UI screenshot where the Saved Vehicles page had overflowing text and Rename/Delete acted on the wrong implicit target. Future work should test long saved vehicle names, many saved rows, and rename/delete flows before packaging.
- Left/Right input rule update: Left may adjust/toggle value rows, but it must not execute one-shot action rows or destructive target rows. Use Enter/Right for action rows such as Save, Rename target, Delete target, Heal, and Refresh. This prevents the earlier Wanted Level-style accidental-navigation/action bugs from reappearing in new pages.
---
## 2026-06-25 Notes - Ghost Town Vehicle Cleanup and Standalone Sound Debug
### Ghost Town / No Vehicles hard rule
- When `ghosttown_ [GhostTown] > NoVehicles` is enabled, the module must delete every nearby vehicle except the vehicle currently being used by the player.
- Do not skip mission/special vehicles in `NoVehicles`. This option is intentionally destructive and the user explicitly wants all vehicles removed except the current player vehicle.
- The cleanup must run immediately when the option is toggled ON, then continue on a short timer while the option remains ON.
- The debug line must expose deletion diagnostics: scanned count, deleted count, forced mission/special count, failed deletion count, and player vehicle skips. If the user reports rare remaining vehicles, inspect `Fail` first. If `Fail=0` but vehicles remain, increase scan radius or check whether the entity is outside the streamed nearby vehicle pool.
- Continue publishing `HasanMerkit.GhostTown.NoVehicles` through `AppDomain.CurrentDomain.SetData` so Story OnlineVehicles can pause while Ghost Town is active.
### Hack Menu must not contain temporary diagnostics
- Temporary diagnostics such as Sound Debug must not be added as Hack Menu modules unless the user explicitly asks for that.
- Sound Debug is now a standalone script: `hasanmerkit_sounddebug.cs` with `hasanmerkit_sounddebug.ini`.
- Keep the Hack Menu focused on its real modules: Player, Ghost Town, Vehicles, and Debug Mode.
### Standalone Sound Debug limitations
- GTA/SHVDN does not expose a reliable public API to enumerate every active audio event the player hears.
- The standalone Sound Debug script should therefore list likely audible sources near the player: player vehicle, nearby vehicle engine/road candidates, nearby human ped voice/footstep candidates, animal candidates, and a note for non-enumerable ambient beds such as wind/city/weather.
- Do not claim this tool reads exact live audio bus/event names. It is a diagnostic aid for tuning `ghosttown_ NoAmbient`.
### Menu overflow rule
- All menu row titles, values, footnotes, and debug lines must be clipped or shortened before drawing because native GTA text rendering does not clip to rectangles.
- Action rows that run on Enter/Right must keep the value column blank. Do not display placeholder values such as `RUN`.
---
## 2026-06-25 Notes - Ghost Town Cleanup, Player Movement, and Sound Debug Removal
### Ghost Town updates
- `ghosttown_ [GhostTown]` now has an action row at the top named `Enable All`. This row must turn ON `NoVehicles`, `NoPeople`, `NoAnimals`, and `NoAmbient` together, run one immediate cleanup pass, and save the config live. It is an action row, so its value column must stay blank.
- `NoPeople` must also remove dead ambient peds lying in the world. Preserve the player and mission/script-owned peds, but do not leave normal dead bodies behind just because they are no longer active pedestrians.
- `NoVehicles` still deletes every nearby vehicle except the player's current vehicle, but it must also preserve vehicles spawned through the Hack Menu `Vehicles` module. Those Hack-spawned vehicles are intentional user vehicles and should bypass Ghost Town cleanup.
- Keep a small Hack-spawned vehicle handle allow-list for this bypass. Clean stale handles periodically so old handles cannot accidentally protect unrelated future vehicles.
- `NoAmbient` remains best-effort only. GTA/SHVDN does not expose a complete reliable list of every audible wind/city/weather sound. Do not keep adding unreliable sound-source guessing tools unless the user asks for a deeper native-specific experiment.
### Player module updates
- Non-disableable module rows such as `Player` should not show `OPEN` in the main menu value column. The arrow already communicates that the row opens a page.
- Add `Fast Run` and `Long Jump` under the Player page and save them to `[Player] FastRun` and `[Player] LongJump`.
- `Fast Run` should be applied every tick with a run/sprint multiplier and reset to normal when disabled.
- `Long Jump` should use a per-frame super-jump native while enabled. While the player is airborne from Long Jump, temporarily protect the player from fall damage. When the player lands and normal `Invincibility` is OFF, remove that temporary protection.
- Use raw native hash constants for movement helper natives if the `GTA.Native.Hash` enum member may be missing in stable/nightly/fallback builds.
### Sound Debug removal
- The standalone `hasanmerkit_sounddebug.cs` diagnostic has been removed from active gameplay. A future ZIP may include a compile-safe placeholder file to overwrite older diagnostic scripts so they no longer load.
- Temporary diagnostic scripts must not stay in normal releases unless they are explicitly requested.
---
## 2026-06-25 Notes - Ghost Town Wanted Suppression, Long Jump Strengths, Vehicle Glass Reinforcement, and World Module
### Ghost Town + police behavior
- When `ghosttown_ [GhostTown]` has both `NoVehicles=1` and `NoPeople=1`, the Player module must force a no-wanted state every tick. Call wanted-level zeroing and police-ignore logic even if `[Player] NeverWanted=0`.
- In this forced Ghost Town state, Player menu wanted controls must be non-actionable. Show the user that the setting is disabled because Ghost Town is controlling it. Do not allow Left/Right/Enter to change `Wanted Level` or `Set Never Wanted` while the forced condition is true.
- This forced state must not overwrite `[Player] NeverWanted` in the config. It is a runtime dependency caused by Ghost Town only.
### Long Jump strength values
- `player_ [Player] LongJump` is no longer a boolean. It must cycle through `Off`, `2x`, `4x`, and `8x` in the menu and should be stored as numeric config values `0`, `2`, `4`, or `8`.
- Keep backward compatibility when reading old configs: `LongJump=1`, `true`, `yes`, or `on` should be interpreted as `2x`.
- Long Jump must still protect against fall damage while airborne, then restore the player's normal damage state after landing unless normal `Invincibility` is enabled.
### Vehicle Invincibility glass lesson
- A one-time vehicle repair is not enough for bulletproof glass. Police or NPC bullets can still break windows after the first repair.
- While `vehicles_ [Vehicles] VehicleInvincibility` is ON, reinforce the current vehicle every tick. Keep entity/vehicle invincibility flags active and repair/fix vehicle windows repeatedly. Rolling windows up each tick is allowed as a best-effort reinforcement.
- Do not rely on `SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(false)` alone for glass protection; it does not reliably stop all window break events.
### New Hack module: World
- Add Hack module `World (world_ [World])` with config section `[World]`.
- Required config keys:
- `EverythingLowPoly=0`
- `ClearAllEntities=0`
- `HideWorldGeometry=0`
- `NoSky=0`
- Menu labels should be friendly: `Everything Low Poly`, `Clear All Entities`, `Hide World Geometry`, and `No Sky`.
- `Everything Low Poly` is best-effort only. A script can encourage lower LOD through LOD-scale overrides, but it cannot guarantee that every map asset swaps to a low-poly version.
- `Clear All Entities` is destructive and should delete nearby non-map entities exposed through SHVDN: vehicles, peds, and props/objects. Preserve the player, the player's current vehicle, and Hack-spawned vehicles that intentionally bypass Ghost Town cleanup.
- `Hide World Geometry` is experimental. SHVDN raw scripts cannot safely unload or hide baked map meshes globally like a graphics/streaming mod. Make the menu honest and use only reversible best-effort visual overrides.
- `No Sky` is also best-effort. Weather/cloud/timecycle natives can reduce or flatten the sky impression, but script access may not truly delete the sky renderer.
- Debug should expose a compact World line with active state and cleanup counters so dangerous World operations can be inspected quickly.
## 2026-06-25 Update Notes - World Safety, Character Swap, and Ghost Town Vehicle Preservation
- Removed the `No Sky` option from the Hack Menu World module. It did not produce a reliable controllable result through raw SHVDN scripts and should not be reintroduced unless a tested native/IPL method exists.
- `Hide World Geometry` must never use black-screen timecycle modifiers such as `NG_blackout`. That approach hides the whole screen and may persist after toggling the option off. If a future AI attempts map-hiding again, it must preserve visible peds/vehicles/entities and must include a tested restore path. Until then, treat map geometry hiding as a safe best-effort dynamic cleanup only.
- Added World child pages: `World Modes`, `Weather`, and `Time`. Child pages must be navigated through the World page, not flattened into the main Hack Menu.
- World Modes are safe ambience presets only. Snow-style modes may use weather types such as `XMAS`/`BLIZZARD` and snow trail/footstep natives, but should not claim to swap baked map geometry unless verified in-game.
- Weather and Time settings are saved to `[World]`. Time supports freeze, hour, and minute. Weather is ignored while a non-normal World Mode is active.
- Ghost Town `No Vehicles` must preserve the player's current or last-used vehicle, not just Hack-spawned bypass vehicles. This prevents the cleanup loop from deleting the vehicle the player is actively using or just exited.
- Added `Player > Change Character` as a child page. It performs model swaps only; it does not change story state, protagonists, missions, or save identity. Use model validity checks (`IsInCdImage`, `IsPed`, `Request`, `IsLoaded`) before `SET_PLAYER_MODEL`.
- The motorcyclist Trevor kills is Johnny Klebitz; use `ig_johnnyklebitz` for that menu entry.