← Portfolio Saarth Kishore Play on itch.io
Live on itch

Case study · Personal project · May 2026 – Present

Beyond Art

Draw-to-manifest sandbox in Unreal Engine 5 — the better you draw, the better it works.

Beyond Art is a third-person creative sandbox where player sketches become playable weapons, ranged gear, and body customizations. A hybrid vision + ink-metrics judge validates drawings and scores stats. The game ships on itch.io while the judge runs as a separate cloud service — so gameplay builds and AI logic update independently.

By the numbers

Baselines from the first playable slice (local melee forge + slow vision score) versus the shipped Mode B build on itch.io.

Forge categories

13

Melee-only prototype → melee + ranged + body customize forges (Q / R / E).

Playable object classes

215+

Sword / generic weapon → swords, axes, spears, daggers, pistols, rifles, bows, bazookas, legs, arms, and aliases.

Score-step latency

10–90s<1s

Ollama validate waits and Gemini score hangs → hybrid path scores with instant ink metrics after validate.

End-to-end “Judging…”

Hang / 60–180s~few sec

Stuck confirm UX and raised HTTP timeouts → validate + instant score; ink fallback when cloud Gemini fails.

Public Windows builds

02

No external players → itch.io channels 0.1.0 and 0.1.1 (~634 MB each).

Who can run the judge

1 PCAnyone

Mode A disk path on the author machine → Mode B HTTPS + Base64 to Render for packaged players.

Download package size

~1.15 GB634 MB

Raw Shipping folder over itch’s 1 GB web cap → butler-compressed Windows zip players can fetch.

Cloud Gemini reliability

Fail-closedPlayable

Datacenter IP blocks → soft-accept + local ink validate so melee / ranged / body still ship stats.

Distribution measured as public Windows builds on itch.io (versions 0.1.0 and 0.1.1). Swap in dashboard download / view / play counts when you want an exact player metric.

The hook

Most sandboxes give you a menu of items. Beyond Art gives you a blank canvas. Want to smash a building? Draw a sword, axe, or boxing gloves. Want to run faster? Draw legs. Want a ranged loadout? Draw a pistol, rifle, or bow — then draw the projectile art.

Three ideas stacked into one fantasy:

“The better you draw, the better it works” — the entire product promise in one sentence.

Player loop

  1. Explore a stylized third-person city sandbox (low-poly / modular plaza).
  2. Open the forge (draw UI) for melee weapons, ranged weapons, or body slots.
  3. Sketch on a 1024×1024 render-target canvas with brush, color wheel, clear/confirm.
  4. Confirm → export PNG → send to the Judge Bridge → validate (+ reject with a clear reason) or score stats.
  5. Equip the drawing as a flat textured weapon / projectile / body customization and play.

Invalid drawings are hard-blocked with a friendly message (empty canvas, obvious rectangles, wrong subject). Valid drawings always produce something usable, with stats clamped so balance doesn’t explode.

Gameplay systems shipped

Drawing & forge

  • In-widget paint on RT_DrawCanvas (additive / composite brush materials).
  • Melee forge, ranged forge (weapon + projectile canvases), body customize slots.
  • Export path via Export Render Target → disk PNG under Saved/DrawingJudge/.
  • Base64 encode for cloud Mode B (LoadPngFileAsBase64 via FileSDK + Low Entry).

Combat & character

  • Third-person character with hotbar weapon slots.
  • Melee damage / durability from judge scores.
  • Ranged: aim, zoom, projectiles, weapon-type anims (pistol / rifle / bow).
  • Body slots (legs / arms) apply stat values from the same judge pipeline.
  • Grip UV rules, color wheel, and Fab character mesh integration.

Recognized / scored subjects

AI judge architecture

The game never embeds API keys. Unreal talks only to a small Python service — judge_bridge.py — over HTTP/HTTPS JSON.

UE game  →  HTTPS POST (image_base64 + metadata)
         →  Judge Bridge (Render / local)
         →  Gemini Flash  (or Ollama / local ink)
         →  JSON stats back to Blueprints

Backends (env-selected)

Why a bridge?

Validate → score pipeline

Confirm runs two async HTTP calls (not one giant request):

1. POST /judge/validate

  • Inputs: image_base64 (or local image_path), expected_subject, description, context.
  • Ink prefilter rejects empty canvases and hollow rectangles.
  • Vision model checks “does this look like a sword / pistol / legs?”
  • Returns bValid, reject_reason, confidence, detected_subject.
  • Hard block in UI on fail — player must redraw.

2. POST /judge/score

  • Same image + ink_area / context.
  • Weapon contexts → damage + durability.
  • Body contexts → stat_value.
  • Gemini score JSON is unreliable → hybrid uses instant ink-based score after validate.
  • Blueprints clamp and apply to equip / HUD.

Example validate body

{
  "image_base64": "<png bytes as base64>",
  "image_path": "C:/.../weapon.png",
  "expected_subject": "sword",
  "description": "sword",
  "context": "weapon"
}

GET /judge/ping gates online vs offline fallback so the game stays playable if the bridge is down.

Mode B — cloud deploy

Local Mode A sent a disk image_path to a Python process on the same PC. Packaged builds can’t do that for strangers. Mode B:

  1. UE exports PNG → reads bytes → Base64 string.
  2. Game POSTs JSON to https://artgame-judge.onrender.com.
  3. Bridge decodes Base64 to a temp PNG, runs validate/score, returns JSON.
  4. GEMINI_API_KEY lives only in Render environment variables.

Cloud vs home network reality

Free-tier Gemini often works from a residential IP but fails from cloud datacenter IPs (403 / empty candidates). The bridge therefore:

Deployed as a Docker web service on Render (Dockerfile + render.yaml), health check on /judge/ping, auto-deploy from GitHub (Saarth09/ArtGame_Judge).

Unreal engineering notes

Hard problems solved

False “not a weapon” rejects

Ink rectangle prefilter treated stick swords (span all four bbox sides) as boxes. Tightened border-ratio rules; Gemini soft-accept + cloud fallback.

Ranged stuck on “Judging…”

Score path waited on flaky Gemini JSON. Switched score to hybrid ink metrics; ensure Blueprint routes ranged → ranged finish equip.

Works locally, fails on Render

Same key/code; Gemini blocked from cloud IPs. Reproduced with live POST; shipped ink fallback so packaged players aren’t bricked.

Packaging blocked by MSVC

UE 5.8 bans mid MSVC toolchains. Updated Visual Studio / MSVC 14.50+ so Shipping Win64 packages with FileSDK / Low Entry C++ plugins.

itch upload > 1 GB

Web upload capped at 1 GB; ~1.15 GB package → butler / itch app channel push (windows), email verification, Public visibility.

Shipping & update model

ChangeWhat you ship
Gameplay, UI, levels, artNew UE Shipping package → butler push to itch (:windows)
Judge prompts, Gemini, validate rulesGit push judge repo → Render auto-deploy (no game rebuild)
PlayersInternet required for judge; first hit may wait on free-tier cold start

Live download: saarth09.itch.io/beyondart. Steam is feasible later with the same Shipping build; Mode B judge stays on Render.

Stack & what I owned

Solo project end-to-end: design, UE gameplay/UI, Python judge service, cloud deploy, packaging, and distribution.

Status

Playable Windows build public on itch.io. Core loop live: draw → validate → score → equip for melee, ranged, and body. Ongoing: balance tuning, more object classes, grip polish, and optional Steam release.