AnyUser Developer Portal
Integrate the universal accessibility standard into your game engine or software. With the Behavioral Interceptor pattern, you override camera transforms, input polling, and audio nodes on boot—ensuring players never experience configuration fatigue.
Drop-in addons/anyuser with GDScript & C# singletons, AnyUserCamera2D, and shaders.
UPM package featuring AnyUserParser, AnyUserCameraShake, and URP colorblind shaders.
C++ Subsystem, Camera Modifier for shake dampening, and Enhanced Input modifiers.
Zero-dependency package for profile parsing, CSS variable injection, and zero-account URL hash sync.
1-Click Bookmarklet and Manifest V3 extension to inject AnyUser onto any active website.
Public, edge-cached JSON Schema with open CORS at /schema/v1/anyuser-schema.json.
Architecture Principle
The "Behavioral Interceptor" Pattern
Traditional accessibility requires sprawling settings submenus. AnyUser shifts responsibility to engine-level interceptors that apply preferences before frame 1:
Ingest Profile
Singleton reads profile.anyuser from local app data or persistent user storage on game boot.
Sanitize & Clamp
Values are validated against Draft-07 bounds (e.g. screen_shake clamped 0.0–1.0).
Inject Interceptors
Overrides camera offsets, input event polling, audio bus filters, and UI canvas scale factors.
Render Frame 1
The game launches fully accessible from the opening splash screen and main menu without user intervention.
Interactive Engine Integrator
Drop-in Engine Scripts & Singletons
Select your game engine and the behavioral interceptor you want to implement to generate copy-paste code:
# AnyUserParser.gd
# Add as an AutoLoad Singleton in Project -> Project Settings -> Autoload
extends Node
var current_profile: Dictionary = {}
var is_loaded: bool = false
signal profile_loaded(profile_data)
func _ready() -> void:
# Check candidate paths: persistent user data, project root, and addon directories
var candidate_paths: Array[String] = [
"user://profile.anyuser",
"res://profile.anyuser",
"res://addons/anyuser/profile.anyuser",
"res://addons/user/profile.anyuser"
]
for path in candidate_paths:
if FileAccess.file_exists(path):
if load_profile(path):
break
func load_profile(file_path: String) -> bool:
if not FileAccess.file_exists(file_path):
push_warning("AnyUser: Profile not found at %s" % file_path)
return false
var file := FileAccess.open(file_path, FileAccess.READ)
var json_str := file.get_as_text()
file.close()
var test_json_conv := JSON.new()
var error := test_json_conv.parse(json_str)
if error != OK:
push_error("AnyUser: Failed to parse JSON: " + test_json_conv.get_error_message())
return false
current_profile = test_json_conv.data
is_loaded = true
apply_all_interceptors()
emit_signal("profile_loaded", current_profile)
print("AnyUser: Profile v%s loaded successfully from %s" % [current_profile.get("version", "1.0"), file_path])
return true
func apply_all_interceptors() -> void:
# 1. Zero-Code Drop-In UI Scaling
var vision: Dictionary = current_profile.get("vision", {})
if vision.has("ui_scale") and get_tree() and get_tree().root:
var scale_factor := float(vision["ui_scale"])
if scale_factor > 0.0:
if get_tree().root.content_scale_mode == Window.CONTENT_SCALE_MODE_DISABLED:
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
get_tree().root.content_scale_factor = scale_factor
# 2. Intercept camera shake trauma factor
if vision.has("screen_shake"):
var shake_val := float(vision["screen_shake"])
if has_node("/root/AnyUserCamera"):
get_node("/root/AnyUserCamera").shake_multiplier = shake_val
elif get_viewport() and get_viewport().get_camera_2d():
var cam = get_viewport().get_camera_2d()
if "shake_multiplier" in cam:
cam.shake_multiplier = shake_val
# 3. Intercept audio bus filters (mono downmix & tinnitus frequency cut)
var audio: Dictionary = current_profile.get("audio", {})
var master_idx := AudioServer.get_bus_index("Master")
if master_idx >= 0 and audio.get("tinnitus_frequency_cut", false):
var lpf := AudioEffectLowPassFilter.new()
lpf.cutoff_hz = 4000.0
AudioServer.add_bus_effect(master_idx, lpf)Schema Specification Reference
Interactive Schema Dictionary (v1.0)
Explore every parameter defined in anyuser-schema.json with mathematical bounds, human rationales, and engine hook recipes:
number (float)
0.0 (Off) to 1.0 (Full)
1.0
Prevents motion sickness, vestibular dysfunction, and migraines caused by violent camera shake during explosions, hits, and recoil.
Multiply all Camera2D/Camera3D randomized impulse offsets by screen_shake. When 0.0, lock the camera to static transform.Grassroots Accessibility
Zero-Studio WaitingCommunity Modding & Runtime Wrappers
Commercial studios often take years to patch accessibility into legacy backlogs. Through community modding frameworks—including BepInEx for Unity, GDWeave for Godot, and UE4SS for Unreal Engine—modders can inject the universal .anyuser standard into existing commercial titles today without source code access.
Universal Profile Discovery Standard
All community wrappers inspect these standard OS locations in prioritized order on game boot:
%USERPROFILE%\.anyuser\default.anyuserStandard global profile location for all desktop PC games.~/.config/anyuser/default.anyuserXDG config directory; also falls back to ~/.anyuser/default.anyuser.~/Library/Application Support/anyuser/default.anyuserNative macOS Application Support directory path.<GameRoot>\anyuser_profile.jsonPer-game local override placed directly alongside the game executable.Intercepts Camera transform shake routines and converts hold keys into toggle latches across commercial Unity titles without requiring source code.
- 1Install BepInEx 5 or 6 into your game's root directory.
- 2Drop the compiled AnyUserModWrapper.dll into BepInEx/plugins/.
- 3The mod reads %USERPROFILE%\.anyuser\default.anyuser on boot and hooks Camera transforms and Input polling without touching game assemblies.
// AnyUserModWrapper.cs
// Universal Accessibility Wrapper for Unity Games (BepInEx 5/6 + HarmonyX)
// Reads standard OS-level AnyUser profile and intercepts camera shake & hold inputs.
using System;
using System.IO;
using System.Collections.Generic;
using BepInEx;
using HarmonyLib;
using UnityEngine;
namespace AnyUser.ModWrapper
{
[BepInPlugin("net.anyuser.modwrapper", "AnyUser Accessibility Wrapper", "1.0.0")]
public class AnyUserPlugin : BaseUnityPlugin
{
public static AnyUserProfile ActiveProfile { get; private set; } = new AnyUserProfile();
private Harmony harmony;
private void Awake()
{
Logger.LogInfo("AnyUser: Initializing Universal Accessibility Interceptor...");
LoadAnyUserProfile();
harmony = new Harmony("net.anyuser.modwrapper");
harmony.PatchAll();
Logger.LogInfo($"AnyUser: Profile loaded (Shake={ActiveProfile.screen_shake * 100}%, HoldToToggle={ActiveProfile.toggle_instead_of_hold})");
}
private void LoadAnyUserProfile()
{
// Standard AnyUser Discovery Paths
string userHome = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string[] discoveryPaths = new string[]
{
Path.Combine(Paths.GameRootPath, "anyuser_profile.json"),
Path.Combine(userHome, ".anyuser", "default.anyuser"),
Path.Combine(userHome, ".config", "anyuser", "default.anyuser")
};
foreach (string path in discoveryPaths)
{
if (File.Exists(path))
{
try
{
string json = File.ReadAllText(path);
ActiveProfile = AnyUserProfile.FromJson(json);
Logger.LogInfo($"AnyUser: Successfully loaded profile from: {path}");
return;
}
catch (Exception ex)
{
Logger.LogWarning($"AnyUser: Failed reading profile at {path}: {ex.Message}");
}
}
}
Logger.LogWarning("AnyUser: No .anyuser profile found in standard paths. Using defaults.");
}
}
// Harmony Patch: Camera Shake Interceptor
// Clamps Camera localPosition offsets to the profile's screen_shake multiplier
[HarmonyPatch(typeof(Camera), "OnPreRender")]
public static class CameraShakeInterceptorPatch
{
[HarmonyPrefix]
public static void Prefix(Camera __instance)
{
if (AnyUserPlugin.ActiveProfile.screen_shake < 1.0f && __instance == Camera.main)
{
// Scale displacement offset towards center anchor
Vector3 currentLocal = __instance.transform.localPosition;
__instance.transform.localPosition = Vector3.Lerp(Vector3.zero, currentLocal, AnyUserPlugin.ActiveProfile.screen_shake);
}
}
}
// Harmony Patch: Hold-to-Toggle Input Interceptor
// Latches discrete key presses into continuous toggle states when requested
[HarmonyPatch(typeof(Input), nameof(Input.GetKey), new Type[] { typeof(KeyCode) })]
public static class InputHoldToTogglePatch
{
private static readonly Dictionary<KeyCode, bool> toggleStates = new Dictionary<KeyCode, bool>();
private static readonly HashSet<KeyCode> targetedHoldKeys = new HashSet<KeyCode>
{
KeyCode.LeftShift, KeyCode.LeftControl, KeyCode.C, KeyCode.F, KeyCode.E
};
[HarmonyPostfix]
public static void Postfix(KeyCode key, ref bool __result)
{
if (!AnyUserPlugin.ActiveProfile.toggle_instead_of_hold || !targetedHoldKeys.Contains(key))
return;
if (Input.GetKeyDown(key))
{
toggleStates[key] = !toggleStates.GetValueOrDefault(key, false);
}
if (toggleStates.ContainsKey(key))
{
__result = toggleStates[key];
}
}
}
[Serializable]
public class AnyUserProfile
{
public float screen_shake = 0.0f;
public bool toggle_instead_of_hold = true;
public float ui_scale = 1.0f;
public bool high_contrast_mode = false;
public static AnyUserProfile FromJson(string json)
{
var profile = new AnyUserProfile();
if (json.Contains("\"screen_shake\":"))
{
var match = System.Text.RegularExpressions.Regex.Match(json, "\"screen_shake\"\\s*:\\s*([0-9.]+)");
if (match.Success && float.TryParse(match.Groups[1].Value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float shake))
profile.screen_shake = Mathf.Clamp01(shake);
}
if (json.Contains("\"toggle_instead_of_hold\":"))
{
profile.toggle_instead_of_hold = json.Contains("\"toggle_instead_of_hold\": true") || json.Contains("\"toggle_instead_of_hold\":true");
}
return profile;
}
}
}AnyUser accessibility wrappers operate exclusively on client-side camera transforms, visual presentation, audio buses, and physical motor accessibility. For titles protected by kernel anti-cheat (e.g., Easy Anti-Cheat, BattlEye), deploy wrappers only in single-player or cooperative PvE modes. For competitive multiplayer, urge developers to integrate our official zero-dependency engine SDK directly.
Created an AnyUser Wrapper for another game?
Share your mod with thousands of players! Submit your wrapper to the official AnyUser community repository.
Developer Sandbox
Live JSON Schema Validator
Paste any .anyuser JSON artifact to test compliance against the Draft-07 specification in real time:
Have feedback or building a new engine SDK?
AnyUser is created as part of Cwtch & Code. Reach out at [email protected] or contribute via GitHub.