Shadow Link's Awakening: Dissecting the Zero-Hardcoded BEJSON 105 React Action-RPG Engine

[LEETHAXOR69 ROOT ACCESS GRANTED] Listen up, wannabe game devs and Unity bloatware victims. Every amateur tutorial on YouTube tells you to hardcode player stats in class files, load 500MB of bloated asset bundles, and let an engine garbage-collect your frame rate into the dirt. Real engineering looks nothing like that. Today we are cracking open one of the sickest real-world applications in /storage/emulated/0/Admin/Dev/React: Sword Slasher RPG: Shadow Link's Awakening (SS2).

This isn't your grandma's Zelda clone. You play as Shadow Link carrying out Lord Ganon's dark commands to infiltrate Hyrule and capture Princess Zelda. But what makes this project an architectural masterpiece is under the hood: 100% data-driven game mechanics powered by BEJSON 105 (Integrity Era), zero-GC pre-allocated AABB collision physics, a real-time Web Audio chiptune synthesizer with zero audio files, and dual-delivery deployment (React 19 Vite SPA + zero-server single-file HTML). Let's dissect the beast.

Table of Contents

  1. Chapter 1: The Dark World Subversion — Shadow Link, Ganon's Command & The Data-Driven Manifesto
  2. Chapter 2: The BEJSON 105 Game Matrix — 20 Authoritative Datasets & Zero Hardcoded Stats
  3. Chapter 3: The Engine Room (bejsonEngine.ts) — O(1) Field Map Caching & Dynamic MFDB Ingestion
  4. Chapter 4: The Kinetic Core (physicsEngine.ts) — Zero-GC Pre-allocated AABB Bounding Boxes & Vector Knockback
  5. Chapter 5: Sonic Retro Alchemy (soundEngine.ts) — Real-time Web Audio Synthesizer Driven by Frequency Matrices
  6. Chapter 6: Presentation, Viewport & Controls — HTML5 Canvas, CRT Scanlines, GameHUD & Mobile GamepadDeck
  7. Chapter 7: The Dual-Delivery Matrix & Embedded AI — Vite SPA, Single-File HTML Compiler & Gemini Advisor

Chapter 1: The Dark World Subversion — Shadow Link, Ganon's Command & The Data-Driven Manifesto

Most retro RPGs are boring rehashes of the same tired trope: wake up in a cozy village, grab a wooden sword, save the kingdom. Sword Slasher 2: Shadow Link's Awakening flips the script completely, subverting The Legend of Zelda: A Link to the Past with surgical dark narrative precision.

The Narrative Inversion

You don't play as the green-hatted hero. You are Shadow Link, a living dark reflection forged in the Dark World by the dark sorcery of Lord Ganon. The game opens in Ganon's Dark Sanctum with an ominous royal directive:

"Awaken, my shadow. The Kingdom of Hyrule sleeps under false peace. Infiltrate the castle, slaughter the royal guard, and capture Princess Zelda. Her blood will shatter the seal on the Sacred Realm!"

Your journey takes you from the Dark World through hidden dimension portals into the heart of Castle Hyrule, turning the familiar palace dungeons into hostile infiltration zones.

The Data-Driven Manifesto: Zero Hardcoded Game Logic

Now here is where typical software engineers fail. In amateur games, you open Player.ts and see garbage like:

// The Amateur Mistake: Hardcoding game stats into engine code
class Player {
    hp = 120;
    speed = 3.2;
    attackDamage = 4;
    swordKnockback = 0.4;
}

The moment a game designer wants to balance a sword, change player movement speed, adjust an enemy's hit points, or add a new biome, they have to touch source code, recompile TypeScript, and risk breaking the game loop. In Sword Slasher 2, there are ZERO hardcoded gameplay constants in the codebase. Every stat, every enemy health pool, every sword swing arc, every dialogue line, and every audio waveform is extracted cleanly into BEJSON 105 matrix tables.

The engine is purely an execution substrate; the data matrix dictates the entire reality of the game world. Let's inspect the raw structural datasets in Chapter 2.


Chapter 2: The BEJSON 105 Game Matrix — 20 Authoritative Datasets & Zero Hardcoded Stats

If you open public/data/ inside the Sword Slasher 2 project, you won't find random JSON blobs or ad-hoc configuration files. You will find an enterprise-grade Multi-File Database (MFDB) governed by the BEJSON 105 (Integrity Era) specification. The entire game universe is decomposed into 20 authoritative matrix tables linked via a master manifest (manifest/105a.mfdb.bejson).

The 20 Authoritative Game Datasets

Matrix Path BEJSON Format Engine Role & Content
manifest/105a.mfdb.bejson 105a Master MFDB manifest linking all 20 entity tables and syncing record counts.
actors/actors.105.bejson 105 Actor identities, faction roles (Dark World vs Royal Army), and visual sprite bindings.
actor_stats/actor_stats.105.bejson 105 Exact HP, attack damage, walk speed, knockback resistance, and AI behavior flags.
biomes/biomes.105.bejson 105 Environmental ambient color palettes, friction coefficients, and lighting parameters.
audio/audio_manifest.105a.bejson 105a Waveform oscillator frequencies, ADSR envelopes, duration, and musical note sequences.
items/items.105.bejson 105 Weapon specifications: Shadow Blade, Dark Boomerang, Hookshot, and recovery potions.
events/events.105.bejson 105 Scripted dialogue triggers, camera pan opcodes, and quest state progression vectors.
levels/levels.105.bejson 105 World coordinates, area boundaries, spawn vectors, and ambient audio bindings.
chunks/cave_chunk_0_0.105.bejson 105 Spatial 2D tile matrices defining dungeon room geometry and collision flags.
object_rules/object_rules.105.bejson 105 Physics interaction rules for destructible bushes, pushable stone blocks, and chests.
objects/objects.105.bejson 105 World object placement coordinates, chest loot tables, and locked dungeon doors.
portals/portals.105.bejson 105 Dimensional warp portal coordinates linking Hyrule Castle with the Dark Realm.
schemas/schema_registry.105a.bejson 105a Canonical type signatures and field validation rules across all game tables.
sprites/sprites_manifest.105a.bejson 105a Sprite sheet atlas coordinates, UV bounding boxes, and animation frame rates.
tiles/tiles_manifest.105a.bejson 105a Tile sheet elevation layers, impassable terrain flags, and water swim masks.
runtime_physics/physics_world.105.bejson 105 Global velocity damping, friction constants, and world boundary limits.
runtime_grid/grid_cells.105.bejson 105 Spatial hash grid partition tables for high-speed collision candidate pruning.
runtime_events/event_bus_log.105.bejson 105 In-memory event bus journal logging fired cutscenes and combat triggers.
runtime_telemetry/frame_telemetry.105.bejson 105 Real-time telemetry: FPS metrics, physics calculation microseconds, and memory draw.
runtime_assets/asset_cache.105a.bejson 105a Preloaded asset registry tracking buffer allocations and image bitmap handles.

A Raw Slice of Actor Statistics

Look at how cleanly actor_stats.105.bejson defines the core combat parameters:

{
  "Format": "BEJSON",
  "Format_Version": "105",
  "Format_Creator": "Elton Boehnen",
  "Records_Type": ["ActorStatRecord"],
  "Fields": [
    {"name": "record_uuid", "type": "string", "field_uuid": "105a0001-2026-1025-9999-000000000001"},
    {"name": "actor_id", "type": "string", "field_uuid": "105a0001-2026-1025-9999-000000000002"},
    {"name": "name", "type": "string", "field_uuid": "105a0001-2026-1025-9999-000000000003"},
    {"name": "health_points", "type": "integer", "field_uuid": "105a0001-2026-1025-9999-000000000004"},
    {"name": "attack_power", "type": "integer", "field_uuid": "105a0001-2026-1025-9999-000000000005"},
    {"name": "movement_speed", "type": "number", "field_uuid": "105a0001-2026-1025-9999-000000000006"},
    {"name": "knockback_resistance", "type": "number", "field_uuid": "105a0001-2026-1025-9999-000000000007"}
  ],
  "Values": [
    ["11111111-1111-4111-8111-111111111111", "actor_shadow_link", "Shadow Link", 120, 4, 3.2, 0.4],
    ["22222222-2222-4222-8222-222222222222", "actor_princess_zelda", "Princess Zelda", 80, 0, 2.0, 0.1],
    ["33333333-3333-4333-8333-333333333333", "actor_ganon", "Lord Ganon", 500, 10, 1.5, 0.95],
    ["44444444-4444-4444-8444-444444444444", "actor_royal_knight", "Hyrule Guard", 80, 2, 2.4, 0.5]
  ]
}

Every single number is fully exposed in human-readable arrays. Want to make Shadow Link move twice as fast? Edit 3.2 to 6.4. Want to buff the Royal Knights? Adjust their attack power. Zero TypeScript recompilation. Zero build step. The engine ingests these vectors at runtime and compiles them into $O(1)$ memory lookups, as we'll see in Chapter 3.


Chapter 3: The Engine Room (bejsonEngine.ts) — O(1) Field Map Caching & Dynamic MFDB Ingestion

How does a high-speed React 19 application ingest 20 raw tabular files without lagging the main UI thread? In src/engine/bejsonEngine.ts, the Bejson105Engine acts as the single source of truth, orchestrating asynchronous loading, schema verification, and $O(1)$ constant-time field access.

Asynchronous Bootstrapping & The Loading Pipeline

When the game initializes, bootEngine() initiates a parallel manifest hydration across all 20 tables:

public async bootEngine(): Promise<boolean> {
  const filesToLoad = [
    { key: 'manifest', url: '/data/manifest/105a.mfdb.bejson' },
    { key: 'schema_registry', url: '/data/schemas/schema_registry.105a.bejson' },
    { key: 'biomes', url: '/data/biomes/biomes.105.bejson' },
    { key: 'levels', url: '/data/levels/levels.105.bejson' },
    { key: 'cave_chunk', url: '/data/chunks/cave_chunk_0_0.105.bejson' },
    { key: 'actor_stats', url: '/data/actor_stats/actor_stats.105.bejson' },
    { key: 'actors', url: '/data/actors/actors.105.bejson' },
    { key: 'items', url: '/data/items/items.105.bejson' },
    { key: 'objects', url: '/data/objects/objects.105.bejson' },
    { key: 'object_rules', url: '/data/object_rules/object_rules.105.bejson' },
    { key: 'portals', url: '/data/portals/portals.105.bejson' },
    { key: 'events', url: '/data/events/events.105.bejson' },
    { key: 'sprites', url: '/data/sprites/sprites_manifest.105a.bejson' },
    { key: 'tiles', url: '/data/tiles/tiles_manifest.105a.bejson' },
    { key: 'audio', url: '/data/audio/audio_manifest.105a.bejson' },
    { key: 'runtime_physics', url: '/data/runtime_physics/physics_world.105.bejson' },
    { key: 'runtime_assets', url: '/data/runtime_assets/asset_cache.105a.bejson' },
    { key: 'runtime_events', url: '/data/runtime_events/event_bus_log.105.bejson' },
    { key: 'runtime_grid', url: '/data/runtime_grid/grid_cells.105.bejson' },
    { key: 'runtime_telemetry', url: '/data/runtime_telemetry/frame_telemetry.105.bejson' }
  ];

  for (const f of filesToLoad) {
    const resp = await fetch(f.url);
    if (resp.ok) {
      const doc: BejsonDocument = await resp.json();
      bejsonGaming.registerDocument(f.key, doc);
    }
  }
  this.loaded = true;
  return true;
}

Enforcing the O(1) Field Map Cache in 60 FPS Game Loops

If you query an actor's attack power 60 times a second using string scans or hardcoded numbers, your game will stutter. In Sword Slasher 2, every table registration passes through bejsonCore.getFieldMap(doc). The column names are compiled into integer offsets in a cached hash map:

// Zero-overhead O(1) property lookup in game physics loop
const statDoc = bejsonGaming.getDocument('actor_stats');
const map = bejsonCore.getFieldMap(statDoc);

// Resolves in O(1) time without hardcoding column numbers
const hpCol = map['health_points'];
const atkCol = map['attack_power'];
const spdCol = map['movement_speed'];

const shadowLinkRow = statDoc.Values[0];
const currentSpeed = shadowLinkRow[spdCol]; // Instant resolution!

Active Runtime Simulation State

The Bejson105Engine manages the reactive game state with zero external framework dependencies:

  • Spatial Position & Orientation: Coordinates (playerX, playerY) and facing cardinal direction (UP, DOWN, LEFT, RIGHT).
  • Vitals: playerHp (120), magicPoints (100), and equipped inventory weapons.
  • Narrative Progression: currentObjective string and active dialogue queues with speaker portraits.
  • Live Telemetry: Real-time frame rates, physics calculation durations, and active collision bodies streamed directly to the HUD.

Chapter 4: The Kinetic Core (physicsEngine.ts) — Zero-GC Pre-allocated AABB Bounding Boxes & Vector Knockback

Every amateur web game developer makes the same fatal mistake: they write collision detection by instantiating new objects in the render loop: const playerBox = { x, y, width, height }. When you have 20 enemies, 10 projectiles, and 50 tile colliders running at 60 FPS, your game allocates tens of thousands of temporary JavaScript objects every single second. The browser’s Garbage Collector (GC) kicks in, pauses execution for 30 milliseconds, and drops frames like a rock. On a mobile phone or Android Termux browser, the game becomes unplayable.

In src/engine/physicsEngine.ts, Elton Boehnen engineered a Zero-GC Axis-Aligned Bounding Box (AABB) physics engine designed specifically for buttery smooth, stutter-free execution.

Pre-Allocated Object Pools & checkAABBRaw

The physics engine eliminates heap allocations completely using pre-allocated object pools and raw numerical comparison primitives:

// Zero-GC AABB Bounding Box Pool & Raw Coordinate Intersections
class PhysicsEngine {
  private boxPoolA: AABBBox = { x: 0, y: 0, width: 0, height: 0 };
  private boxPoolB: AABBBox = { x: 0, y: 0, width: 0, height: 0 };

  // Operates directly on raw register numbers — ZERO object allocation!
  public checkAABBRaw(
    ax: number, ay: number, aw: number, ah: number,
    bx: number, by: number, bw: number, bh: number
  ): boolean {
    return (
      ax < bx + bw &&
      ax + aw > bx &&
      ay < by + bh &&
      ay + ah > by
    );
  }
}

By comparing raw numerical coordinates directly, the collision engine never touches the JavaScript heap. Memory allocation during combat is exactly 0 bytes per frame.

Directional Vector Knockback & Resistance Damping

When Shadow Link slashes a Royal Guard with the Shadow Blade, the combat feels punchy and tactile because of mathematical vector impulse calculations:

public calculateKnockback(
  sourceX: number, sourceY: number,
  targetX: number, targetY: number,
  force: number, resistance: number
): KnockbackState {
  const dx = targetX - sourceX;
  const dy = targetY - sourceY;
  const dist = Math.hypot(dx, dy) || 1; // Prevent division by zero
  
  // Resistance factor pulled directly from actor_stats.105.bejson
  const effectiveForce = Math.max(0, force * (1 - resistance));
  
  return {
    vx: (dx / dist) * effectiveForce,
    vy: (dy / dist) * effectiveForce
  };
}

Notice that resistance is not an arbitrary constant; it is ingested directly from column 6 of actor_stats.105.bejson. Lord Ganon has a knockback_resistance of 0.95, making him an unmovable colossus, while lightweight guards have a resistance of 0.5, flying backward when hit by Shadow Link's charge attack. Friction coefficients defined in runtime_physics/physics_world.105.bejson decay velocity per tick, delivering authentic 16-bit physical weight.


Chapter 5: Sonic Retro Alchemy (soundEngine.ts) — Real-time Web Audio Synthesizer Driven by Frequency Matrices

Do you know what makes most modern web games ridiculously bloated? Audio assets. A single 2-minute MP3 background track is 5MB. A pack of sword swings, footsteps, and enemy grunts adds another 20MB. Before the player even sees the title screen, their browser has to download 40MB of binary sound buffers. In Sword Slasher 2, the total disk space used by audio files is exactly ZERO bytes.

In src/engine/soundEngine.ts, Elton Boehnen engineered a pure Web Audio API retro chiptune synthesizer. Every sound effect, sword swing, magic explosion, and atmospheric music theme is synthesized in real time directly from frequency nodes defined in audio_manifest.105a.bejson.

The Frequency Specification Contract

Instead of storing binary audio samples, audio_manifest.105a.bejson stores pure mathematical sound recipes:

export interface SoundEffectFrequencySpec {
  uuid: string;
  slugCode: string;
  title: string;
  waveform: OscillatorType | 'noise'; // 'square' | 'sawtooth' | 'sine' | 'triangle' | 'noise'
  startFreq: number;
  endFreq: number;
  rampType: 'exponential' | 'linear' | 'constant' | 'sequence';
  durationMs: number;
  volumeRatio: number;
  filterType: 'none' | 'bandpass' | 'highpass' | 'lowpass';
  filterCutoffHz: number;
  filterQFactor: number;
  noteSequence: Array<{ freq: number; dur: number; bass?: number }>;
  isLooping: boolean;
}

Synthesizing Combat SFX from Raw Math

When Shadow Link swings the Shadow Blade, soundEngine.playSfx('sword_slash') fires. The audio hardware doesn't decode an MP3; it modulates an oscillator in real time:

  1. Oscillator Allocation: Spawns a high-frequency oscillator (e.g. 420 Hz) using a gritty sawtooth or square waveform.
  2. Exponential Frequency Sweep: The frequency is ramped down exponentially to 80 Hz over 110 ms, replicating the swooshing air resistance of a steel blade.
  3. White Noise Burst: Simultaneously mixes a 20ms burst of procedurally generated white noise (from a reusable AudioBuffer) filtered through a bandpass filter to give the slash visceral weight.
  4. Gain Envelope: The gain node executes an Attack-Decay envelope that cuts smoothly to zero, preventing any audio popping or clicking artifacts.

Procedural Dark Chiptune Music Generator

The background music for Ganon's Dark Sanctum isn't a recorded loop — it is a live arpeggiated sequencer. The engine steps through the noteSequence array from audio_manifest.105a.bejson, scheduling dual-channel square wave oscillators and a triangle wave sub-bass in precise microsecond intervals. The result is haunting, authentic NES/SNES retro dark chiptune music that takes up less than 2 kilobytes of BEJSON text.


Chapter 6: Presentation, Viewport & Controls — HTML5 Canvas, CRT Scanlines, GameHUD & Mobile GamepadDeck

A game can have the best data architecture and physics engine in the world, but if the presentation layer is clunky or the controls lag, nobody will play it. In Sword Slasher 2, the presentation layer balances pure retro 16-bit SNES aesthetics with modern React 19 component responsiveness.

The 2.5D Canvas Viewport & Y-Sorted Depth

Inside src/components/GameViewport.tsx, rendering executes through a hardware-accelerated HTML5 <canvas> element driven by requestAnimationFrame. Two critical techniques ensure pixel-perfect presentation:

  1. Y-Sorted Depth Rendering: In top-down 2D action games, actors must appear in front of objects when standing below them, and behind objects when standing above them. Before rendering a frame, all visible actors, destructible pots, and enemies are collected into a flat render array and sorted by their bottom coordinate:
    renderables.sort((a, b) => a.renderY - b.renderY);
    This delivers flawless 2.5D visual depth with zero Z-fighting.
  2. Camera Lerp & Bounding Clamping: The camera doesn't snap rigidly to Shadow Link; it smoothly interpolates (lerp) toward the player's position, clamped strictly to level boundary coordinates from levels.105.bejson. Screen shake offsets are injected dynamically during critical sword impacts.
  3. CRT Retro Shader Overlay: An optional toggleable post-processing layer injects authentic arcade CRT scanlines and subtle radial vignette shadows without dragging down frame rates.

The GameHUD: Quarter-Heart Precision

In src/components/GameHUD.tsx, the player's health is rendered using classic Zelda heart containers calculated down to quarter-heart precision. A player with 120 HP has 15 total hearts (each heart representing 8 HP). The component calculates full, half, and quarter-heart icons using pure math:

// Heart container calculation in GameHUD
const totalHearts = Math.ceil(maxHp / 8);
const currentEighths = Math.max(0, Math.min(hp, maxHp));

const hearts = Array.from({ length: totalHearts }, (_, i) => {
  const heartValue = Math.max(0, Math.min(8, currentEighths - (i * 8)));
  return heartValue; // 8 = Full, 4 = Half, 2 = Quarter, 0 = Empty
});

Alongside health, the HUD streams real-time magic meters, the equipped secondary item, and a live BEJSON Telemetry Badge displaying current FPS and physics calculation latency in microseconds.

GamepadDeck: High-Precision Mobile Touch Controls

Most browser games are unplayable on mobile because touch controls feel like greasy, unresponsive glass. src/components/GamepadDeck.tsx solves this with an ergonomic touch overlay designed specifically for Android Termux mobile viewports:

  • Virtual Analog Joystick: A dynamic floating thumbstick that calculates 360-degree vector angle and magnitude, snapping cardinal directions to Shadow Link's 4-way walk animations.
  • Multi-Touch Action Buttons: Dedicated touch zones for [ATTACK] (Shadow Blade slash), [INTERACT] (open chest, talk to Ganon), and [ITEM] (throw Dark Boomerang). Pointer events handle simultaneous multi-touch inputs without blocking or gesture interference.

The In-Game BejsonDatabaseView

Ever wanted to inspect the database running your game while playing? Pressing the Database tab opens BejsonDatabaseView.tsx, freezing gameplay and displaying an interactive, searchable matrix inspector of all 20 live BEJSON tables. You can inspect enemy spawn points, verify item stats, and watch runtime event logs in real time.


Chapter 7: The Dual-Delivery Matrix & Embedded AI — Vite SPA, Single-File HTML Compiler & Gemini Advisor

Here is the final test of real software architecture: how versatile is your deployment pipeline? If your game only runs when an active Node.js server is spinning, or if packaging it requires downloading gigabytes of Electron bloat, your architecture is fragile. Sword Slasher 2 delivers a masterclass in Dual-Delivery Engineering paired with embedded AI intelligence.

Pipeline 1: The Modern React 19 / Vite 8 Production SPA

For modern web deployment, the project builds as a modular Single Page Application (SPA):

  • Vite 8 & Tailwind CSS: High-speed Hot Module Replacement (HMR) and optimized tree-shaken production bundles.
  • Zero-Server Relative Build: Running ./node_modules/.bin/vite build --base=./ rewrites all internal asset references into relative paths (./assets/...). This allows the entire production dist/ directory to be loaded directly from local file storage or embedded inside Android WebViews without requiring an HTTP origin server.

Pipeline 2: The Zero-Server Standalone HTML Compiler (compiler.py)

In Gaming/PY/compiler/compiler.py, Elton Boehnen created a remarkable piece of toolchain automation: a standalone Python data compiler that transforms the entire game into a single self-contained HTML file (standalone_game.html).

# The Python Standalone Compiler In Action
cd Gaming/PY/compiler
python3 compiler.py
  1. MFDB Matrix Ingestion: The compiler crawls public/data/, parses all 20 raw BEJSON 105 datasets, and verifies schema integrity.
  2. Inlined Data Bundling: All 20 tables are serialized into compact, inlined JavaScript global constants.
  3. Monolithic Synthesis: HTML structure, CSS styling, canvas rendering loop, AABB physics, Web Audio synthesizer, and BEJSON data tables are welded into a single 125 KB file.

Double-click standalone_game.html on any computer, phone, or tablet in the world, and the game launches instantly. Zero npm install. Zero web server. Zero internet connection. Just pure, unadulterated retro gaming powered by BEJSON 105.

Embedded Google Gemini AI Studio Advisor

Need real-time architectural advice or lore hints while playing? In server.ts, an embedded Express backend interfaces with the Google Gemini 3.6 Flash API:

// server.ts: Google Gemini AI Advisor Proxy
app.post('/api/gemini/advisor', async (req, res) => {
  const { prompt, gameState } = req.body;
  // Dispatches to Gemini 3.6 Flash with full BEJSON schema grounding
  const advisorResponse = await dispatchGeminiAdvisor(prompt, gameState);
  res.json({ advice: advisorResponse });
});

Players can open the in-game Settings modal and consult Lord Ganon's dark AI advisor for gameplay hints, level navigation, and live architectural auditing of the BEJSON tables. It demonstrates how modern cloud AI and deterministic local flat-file databases can coexist in complete harmony.

[LEETHAXOR69 EPILOGUE] You've just walked through the complete architectural autopsy of Sword Slasher RPG: Shadow Link's Awakening. 100% data-driven game mechanics, 20 authoritative BEJSON 105 matrix tables, $O(1)$ field-map caching, Zero-GC pre-allocated collision physics, zero-asset Web Audio synthesis, and a 125KB standalone single-file compiler. Next time someone tells you that React is "too slow for real games" or that games require opaque binary formats, show them SS2 and watch them choke. Class dismissed.


Post complete. All 7 chapters compiled and published by Leethaxor69.


Related Content