Open-World Narrative · Features

Content, Creator Tools & Workshop

A focused page within the Open-World Narrative Features documentation. The full map and every sibling page live in the Features hub.

6sections12 minread1diagram

On this page

V5 ships as one UE5 open world worn six ways, and a game that wide only stays alive if the people who play it can also build for it. This page covers the half of that promise that faces the maker rather than the player: the creator suite — the in-editor tools that let a designer (or, through Workshop, a player) author a playable detective case, a multi-protagonist heist, a mission, or a cinematic without writing engine code — and the Workshop, the in-game distribution layer that takes that authored output, pre-screens it, moderates it, curates it, lets others discover and subscribe to it, and (post-Year-1) sells it with a creator revenue share. The throughline is a single discipline: a creator authors data, not code, and that data is validated by the same runtime rules the live game will judge it under, so a case that passes the editor is guaranteed solvable in play. The strongest, most deeply-implemented piece is Case Author (the V5CaseAuthor module), which authors the Vice-Squad detective cases the Mind Palace later solves; the broadest is V5WorkshopEditor, which carries discovery, subscription, curation, ML moderation, and the paid-mod marketplace. Both are real, compiled UE5 C++. This page tours them on the maker's side of the menu and is honest about where the runtime stops and the art begins. For the full feature scope this slots into, start at the hub: ../V5_features.md.

What ships, honestly#

The C++ logic, the JSON manifests, and the automation tests are real, committed, and compiled to on-box Linux editor binaries (built as the ueagent user, since the editor refuses root); the 3-D art those systems point at is the manifest-referenced surface that, per the V5 posture, is not checked in as binary .uasset. Four honest layers:

  • Real, built, and tested. Five creator-suite modules compile to committed .so binaries under V5/ue/Binaries/Linux/: libUnrealEditor-V5CaseAuthor.so, …-V5HeistAuthor.so, …-V5MissionEditor.so, …-V5Cinematics.so, and …-V5WorkshopEditor.so. Each ships IMPLEMENT_SIMPLE_AUTOMATION_TEST suites that assert specific authored counts and computed verdicts — not truthiness. Case Author's draft validation, the Workshop's discovery filter/sort, the ML pre-screen risk scoring, the revenue-share basis-point math, and the auto-update planner are all genuine domain logic.
  • Authored content is data, validated on load or on build. The case-author templates, the workshop catalog, the curated showcase, the moderator dashboard, and the paid-mod marketplace are committed manifests under each plugin's Content/Data/ with a schemaVersion gate, mirrored by the runtime modules and cross-checked by Python validators in V5/tools/.
  • Honest fail-loud seams. Every Workshop action — publish, subscribe, auto-update, marketplace purchase, pre-screen — builds a real FV5OnlineServiceRequest and dispatches it through UV5_Online_ServiceCatalog::ExecuteRequest, which returns 202/200 on a healthy service, 503 + queued-offline on an outage, and 401 when the JWT is empty. These refuse to fabricate a success they didn't get; the real FHttpModule transport lives in V5OnlineServices (proven by a gated live round-trip, see Modes & Multiplayer).
  • Art referenced, not committed. Preview worlds (/Game/V5/Editor/CaseAuthor/L_HomicideCasePreview), marketplace preview images (/Game/V5/UI/Workshop/Marketplace/…), and spotlight portraits are asset paths named by manifest. They are the UE-art surface V5 keeps out of git; the logic that consumes them is here, the binary art is not.

The creator suite: authoring under the runtime's rules#

The monolith (features§"Creator Suite") lists nine tools — Mission Editor, Heist Author, Case Author, Contract Author, Ship Loadout, Bestiary, Cinematic Director, Cross-Cell Replay Editor, Workshop Publisher — each "built on the UE Editor with custom Slate panels … emitting a typed USTRUCT data file the runtime loads." The committed, separately-compiled modules are Mission Editor, Heist Author, Case Author, Cinematic Director, and the Workshop browser (plus the V5Mode_Replay plugin carrying the Cross-Cell Replay Editor manifest); Contract Author, Ship Loadout, and Bestiary are named in the tool table as Mission-Editor templates rather than standalone modules. The exemplar — and the one that binds the suite to the Mind Palace — is Case Author.

Case Author: a typed model, not a blob#

V5CaseAuthor's Build.cs is the tell: it depends on V5Investigation, V5Interrogation, and V5OnlineServices alongside Slate/SlateCore, so the editor tool is built on the very runtime types a played case uses, not a parallel authoring model. V5CaseAuthorTypes.h defines the whole authoring surface as USTRUCTs: an FV5CaseAuthorTemplate carries a CaseId, a BaseInterrogationSceneId, an EV5Cell, a PreviewWorldPath, a WorkshopCategoryTag, and floor requirements (RequiredClueCount = 4, RequiredInterrogationQuestionCount = 3). An FV5CaseAuthorDraft is the editable document: an array of FV5CaseAuthorCluePlacement (each wrapping a real FV5InvestigationClueDefinition plus a world transform and interaction radius), the FV5InterrogationSceneDefinitions, and an array of FV5CaseAuthorInterrogationBranch mapping a source question to an EV5InterrogationChoice, a required-evidence id, and success/failure next-question ids. The BuildTemplates catalog ships three launch templates — case.vice.homicide.001, case.vice.narcotics.001, case.vice.corruption.001 (V5CaseAuthorSystems.cpp:254), the Period-cell "Vice-Squad-style case authoring" the monolith names.

BuildDraftFromTemplate (:309) earns trust. It loads the template's interrogation scene through the runtime's own UV5_Interrogation_TellLibrary::FindScene (falling back to a fully-formed FallbackScene), synthesizes clue placements from the scene's required-evidence ids plus rotating extras (scene_photo, timeline_note, witness_pin, lab_report) until RequiredClueCount is met, each clue stamped with four FV5InvestigationDetailSpots, then walks the questions deriving the correct authored choice from each question's truth-state — CorrectChoiceForQuestion maps Truthful→Truth, Withholding→Doubt, Lying→Lie (:63). The draft a designer starts from is therefore already a self-consistent, runtime-shaped case.

Validation is the contract, and it's domain-specific#

ValidateDraft (V5CaseAuthorSystems.cpp:324) is the heart of the tool, and it is not a shape check. It runs three graded sub-passes setting bCluePlacementValid / bInterrogationValid / bBranchValid independently:

  • Clues — at least four placements, ids unique, each clue belonging to the active case, each carrying a scene id, at least three detail spots, and a positive interaction radius.
  • Interrogation — every scene belongs to the case, at least three questions, and the load-bearing rule: a Lying question must be catchable with placed evidence, checked by calling the runtime's UV5_Interrogation_EvidenceBackedLie::CanChallengeWithLie(Question, EvidenceInventory) (:357-360) against an inventory built from the draft's own clue placements.
  • Branches — every branch maps to a question that exists, and the (question, expected-choice, has-evidence) triple must ResolveInput to bCorrect through UV5_Interrogation_TruthDoubtLie::ResolveInput (:376); every question needs a branch and every branch needs a success path.

Because both checks call the same V5Interrogation resolvers the runtime uses, a case that passes the editor is guaranteed solvable under the live rules — the difference between authoring tooling and a CRUD form. The three automation tests (V5.CaseAuthor.Catalog, .PanelAuthoring, .WorkshopPublish, V5CaseAuthorTests.cpp) drive the full edit loop — placing a clue, re-prompting a question, re-pathing a branch — and re-assert validity after each mutation.

Publish: a real request with a fail-loud seam#

BuildWorkshopPublishPlan (V5CaseAuthorSystems.cpp:454) assembles an FV5OnlineServiceRequest via UV5_Online_WorkshopClient::BuildPublishRequest, targets /v5/workshop/case-author/publish, and serializes a payload carrying the clue/scene/branch counts, the valid flag, and moderationState: "pending". bReadyToPublish is true only when the draft is valid and an account id and JWT are present (:473). PublishToWorkshop hands the request to ExecuteRequest, and the automation test pins the seam: 202 on a healthy service (V5CaseAuthorTests.cpp:141), 503 + bQueuedOffline on an outage, 401 when the JWT is empty. The visible tool is SV5CaseAuthorPanel — a real Slate widget, a four-column SHorizontalBox (Clues / Interrogation / Branches / Validation+Workshop) with Validate, Preview, and Publish SButtons whose IsEnabled is wired to bSupportsCluePlacement && bSupportsInterrogationTree and WorkshopPlan.bReadyToPublish — and the committed case_author_manifest.json mirrors the module's counts under schemaVersion: 1. The Heist Author and Cinematic Director follow the same shape (typed draft → graded validation → gated FV5OnlineServiceRequest) over their own runtime types.

The Workshop: discovery, curation, moderation, marketplace#

V5WorkshopEditor (plugin V5Mode_Editor_Workshop, cell MindPalace) is the in-game distribution surface for everything the suite emits, and it is the broadest single module on this page — a 1,400-line systems file and a 900-line type header. Its Build.cs depends only on V5Core and V5OnlineServices, because Workshop never re-implements an online call: it composes the shared service seam.

The catalog, discovery, and subscriptions#

BuildCatalog assembles eight launch browse items across every content kind — Mission, Heist, CaseFile, ColdCasePack, HordeMap, plus the VehicleBlueprint and PaidModPack kinds — and then appends the 50 curated community heists, so the catalog ships 58 items (V5WorkshopEditorTests.cpp:72). ApplyDiscoveryFilter (V5WorkshopEditorSystems.cpp:1249) is a real query: it filters by free-text (matching title, id, or category, case-insensitively), category tag, cell, featured-only, and subscribed-only, then sorts curator- featured first, then by descending rating. BuildSubscriptions derives a subscription list from the items a player follows, and BuildAutoUpdatePlan (:1329) emits one /v5/workshop/subscriptions/update request per subscription whose available version exceeds its installed version — semantic-version auto-update, with a bNeedsRestart flag only for horde-map content. The V5.WorkshopEditor.BrowseSubscribe test exercises the full loop and pins the seam at 202/503/401.

Three curation surfaces sit on top of the catalog. Five curator slots pin hand-picked items in order. The Community Heist Hub (BuildCuratedCommunityHeists, :516) carries the Year-1 Top 50 player-created heists — 50 named entries under the workshop.heist.player_created category, each with a curator rank, a rating that decays with rank, and a source heist-author template — and a workshop.heist.player_created discovery filter returns exactly those 50 (V5WorkshopEditorTests.cpp:214). The main-menu curated showcase (BuildMainMenuCuratedShowcase, :623) feeds six auto-advancing carousel slides (8-second dwell) plus twelve monthly community spotlights keyed 2026-05 through 2027-04, each spotlight gated on bPrivacyConsent and bTrustSafetyApproved before it can surface. A separate vehicle-blueprint share path publishes data-only Tier-2 vehicle blueprints (seven parts) through /v5/workshop/vehicle-blueprints/share.

Moderation: the ML pre-screen and the community dashboard#

Moderation is a three-layer pipeline, and the first layer is real code. EvaluateContentPreScreen (V5WorkshopEditorSystems.cpp:1355) computes a risk score from ReportCount × 8, +5 for high subscriber reach (≥10,000), −10 for a trusted creator, plus a per-signal weight for each risk tag — Spoiler 25, Profanity 35, CopyrightRisk 45, PersonalData 55, StabilityRisk 40 — clamped to 0–100. The score then routes deterministically: ≥85 auto-rejects, ≥70 escalates, ≥35 needs human review, below that auto-approves (model version ml.workshop.prescreen.v1). BuildYear1ModeratorDashboard runs that classifier across twelve queue items, and the V5.WorkshopEditor.ModeratorTools test pins the aggregate — 7 pending, 3 escalated, 3 auto-approved, 2 auto-rejected — and asserts the clean item auto-approves while the high-risk item auto-rejects. Above the ML layer sit community report queues and paid human moderators with a DSA-compliant appeal path; the dashboard exposes /v5/workshop/moderation/dashboard and /v5/workshop/moderation/pre-screen.

The paid-mod marketplace#

The post-Year-1 paid-mod marketplace (BuildPaidModMarketplace, :659) lists six data-only PaidModPacks, one per browsing cell, each with USD pricing (≥$0.99), a SKU, KYC/tax/refund eligibility gates, and a preview image path. ValidatePaidModMarketplace (:1148) enforces the economics exactly: the revenue-share policy must sum to 10,000 basis points across creator 7000 (70%), platform 2000, creator-fund 500, chargeback-reserve 300, and tax-reserve 200, with a 30-day payout cadence and a $25 minimum. It demands one payout row per listing (each with positive gross/net/fee/reserve and a /v5/workshop/marketplace/payouts endpoint), a sample purchase that grants an entitlement and books revenue share, and the full data-only / ranked-PvP-disabled / KYC / tax / refund posture. The V5.WorkshopEditor.PaidModMarketplace test asserts the 70/20/5 split and the 10,000-bps total directly.

flowchart TD subgraph author["Creator suite (in-editor)"] CA["V5CaseAuthor<br/>ValidateDraft + publish plan"] HA["V5HeistAuthor / MissionEditor /<br/>Cinematics"] end CA -->|"FV5OnlineServiceRequest<br/>/v5/workshop/case-author/publish"| EXEC{{ExecuteRequest<br/>fail-loud seam}} HA --> EXEC EXEC -- "healthy" --> PRESCREEN["EvaluateContentPreScreen<br/>ml.workshop.prescreen.v1"] EXEC -- "outage" --> Q503["503 + queued offline"] EXEC -- "no JWT" --> Q401["401 auth.jwt.required"] PRESCREEN --> RISK{risk score 0–100} RISK -- "&lt;35" --> APPROVE[AutoApproved] RISK -- "35–69" --> HUMAN[NeedsHumanReview] RISK -- "70–84" --> ESC[Escalated] RISK -- "&ge;85" --> REJECT[AutoRejected] APPROVE --> CAT[(Workshop catalog<br/>58 items)] HUMAN --> DASH[Moderator dashboard<br/>community + appeals] DASH --> CAT CAT --> DISC["ApplyDiscoveryFilter<br/>featured-first, rating-sorted"] DISC --> SUB["subscribe + auto-update<br/>semantic versions"] CAT --> CUR["curator slots · Top 50 ·<br/>main-menu showcase"] CAT --> MKT["paid-mod marketplace<br/>70/20/5/3/2 bps = 10000"] MKT --> ENT["purchase → entitlement<br/>+ revenue share booked"]

The integrity gates: Python validators#

Around the C++ sit a wall of Python validators in V5/tools/ — one per Year-1 Workshop feature (workshop-curated-showcase, workshop-moderator-tools, modder-marketplace, heist-author-top50, plus cross-cell-replay-editor, cinematic-director-mode, and the per-cell content validators). These are not shape stubs. validate-modder-marketplace.py, for example, loads year1_modder_marketplace_manifest.json, asserts every sourceSystems path exists, checks six listings across six unique cells, verifies the revenue-share basis points total 10,000 with a 70% creator floor, confirms the runtime types (FV5WorkshopPaidModListing, FV5WorkshopRevenueSharePolicy, …) and system functions (BuildPaidModMarketplace, ValidatePaidModMarketplace, …) are present in the C++ source, that the five marketplace endpoints appear in the service contract, controller, contract test, and shared runtime, that the features and architecture docs name the feature, and that the corresponding TODO is checked. Each is wrapped by a pytest shim (test_validate_*.py), so the manifest, the C++, the service contract, and the prose cannot drift apart without a red test. This is the cross-reference spine that keeps "the doc says X" honest against "the code does X."

Community surfaces around the Workshop#

The Workshop does not stand alone; V5/community/customer-support-community-manifest.json wires it into the live community program. Community ambassadors carry a workshop-curator role (and a gallery-curator role) with canCurate: true but canModerate: false and canViewPrivatePlayerData: false — they seed and spotlight, they do not adjudicate — under a conduct agreement and a 30-day review cadence, with at least 48 active ambassadors across NA/EU/LATAM/APAC. A Hall of Fame public API surfaces a workshop-contributors category (ranked by a curated install/rating composite, privacy-opt-out respected) alongside mind-palace-solves, and a weekly Player of the Week draws nominations partly from workshop curators. Tier-1 chat (60-second SLA) and tier-2 ticketing route moderation appeals and DSAR requests, closing the loop between a creator's upload, its moderation, and its recognition. These surfaces are detailed in Live Service & Community.

Edge cases & connections#

  • An unsolvable case cannot publish. A Lying interrogation question with no catchable planted evidence fails ValidateDraft via the runtime's evidence-backed-lie resolver, bReadyToPublish stays false, and the Publish button is disabled — the suite will not let a designer ship an unwinnable interrogation.
  • High-risk uploads never auto-publish. A pre-screen score ≥85 auto-rejects and ≥70 escalates before any human sees it; the score is computed from real report/reach/trust/signal inputs, not a coin flip.
  • Offline / unhealthy backends fail loud. Publish, subscribe, auto-update, and purchase all surface 503 + queued-offline (where the endpoint supports it) or 401 on a missing JWT; the editor's job is a correct, gated request and it does exactly that, deferring the live HTTP transport to V5OnlineServices.
  • Paid mods are fenced. Data-only, disabled in ranked PvP, KYC- and tax-gated, with a refund window — and the 70/20/5/3/2 basis-point split is asserted by both the C++ validator and the automation test, so the economics cannot drift.
  • Where the cases get played. The interrogation rig the Case Author validates against and the cross-cell deduction layer that solves the published cases are the Mind Palace; its architecture companion carries the data-contract tables.
  • Where this sits in the menu. The modes that host workshop content (and disable it in ranked/esports) are in Modes & Multiplayer; the seasonal calendar, creator programs, and community recognition that schedule and surface this output are in Live Service & Community.
  • The deep engine treatment. The Slate-panel architecture, the GameFeature plugin packaging, and the validation-as-runtime-rules design are expanded in the architecture companion, ../architecture/creator-suite-and-mind-palace.md.

Together the creator suite and the Workshop are V5's answer to "a world this wide needs its players to extend it": tools that author content under the runtime's own rules, and a distribution layer that pre-screens, moderates, curates, and (eventually) pays for it — real in logic, honest about the art it reaches for.