💀 Case Study: ODOOM
ODOOM is a fork of UZDoom — the popular Doom source port — extended with full OASIS WEB4 and WEB5 integration via OGLib (shared C helper layer) and the OGEngine Client C ABI. Players authenticate as OASIS Avatars, earn karma for kills and completions, carry cross-game inventory shared with OQuake and Our World, and advance quest objectives that persist across all three games. ODOOM is the reference game for how to integrate any C/C++ title with the OASIS Omniverse in minutes.
Tech stack
- Base engine: UZDoom (C/C++) extended with OGEngine OASIS layer
- OGLib: shared C helper library — config loading, beamin/beamout, session forwarders, cross-game mapping (
oglib.h) - OASIS integration: OGEngine Client — a C ABI (
ogengine_*functions) wrapping WEB4 + WEB5 - OASIS WEB4: Avatar auth, Karma (kills/completions), cross-game Inventory, HyperDrive save data
- OASIS WEB5: Missions, Quests, Inventory Items (keys/weapons), Cross-game quest chains
- Shared with: OQuake (same quest chain), Our World (same inventory)
What is OGEngine?
OGEngine is the full OASIS game integration stack: OGEngine Client (the C# NativeAOT DLL), WEB4, WEB5, and the optional OGLib C helper layer that sits on top. OGLib handles the boilerplate every game needs — config loading, session management, beamin/beamout workflow, and cross-game asset mapping — so game-specific code stays lean and only contains engine hooks.
uzdoom_star_integration.cpp (ODOOM engine hooks only)
↓ #include "oglib.h"
OGLib (shared C library — config, beamin, session shims, cross-game)
↓ star_api_* calls
OGEngine Client (C# NativeAOT → star_api.dll)
↓ HTTPS
WEB4 / WEB5 OASIS APIs
Step 1 — Initialise OASIS at Startup
// uzdoom_star_integration.cpp — OGLib handles config + session boilerplate #define OGLIB_SESSION_IMPL #define OGLIB_CONFIG_IMPL #define OGLIB_BEAMIN_IMPL #include "oglib.h" // config, beamin, session forwarders, cross-game, JSON/str utils #include "star_api.h" void I_OASISInit(void) { // OGLib loads oasisstar.json, sets the API URL, and restores saved JWT oglib_config_load(&g_star_config, "oasisstar.json", NULL, NULL); star_api_init(g_star_config.star_api_url); oglib_beamin_restore_session(&g_star_config); }
Step 2 — Avatar Login Screen
// Called from the ODOOM login menu void M_OASISLogin(const char *email, const char *password) { star_api_login_async(email, password, on_login_result); } static void on_login_result(star_api_result_t *r) { if (r->is_error) { M_ShowError(r->message); return; } config_set_string("oasis_token", r->token); G_StartGame(); // proceed to game }
Step 3 — Karma for Kills & Level Completion
// p_interaction.c — called when monster dies void P_KillMobj(mobj_t *source, mobj_t *target) { // ... existing Doom kill logic ... // Award karma for the kill int karma = monster_karma_value(target->type); // e.g. Cacodemon = 5, CyberDemon = 100 star_api_award_karma(karma, "Kill"); } // g_game.c — called when level exits void G_WorldDone(void) { star_api_complete_mission_objective(current_mission_id, current_objective, avatar_id); star_api_award_karma(500, "LevelComplete"); }
Step 4 — Cross-Game Inventory (Keys)
The Crimson Key found in ODOOM's E1M1 is stored in the OASIS cross-game inventory. In Our World, a secret AR door only opens if the player holds this key.
// p_map.c — when player picks up a key void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher) { switch (special->sprite) { case SPR_RKEY: // Red (Crimson) Key star_api_add_inventory_item("crimson_key", "Crimson Key", "Key discovered in Doom E1M1 — opens the citadel gate."); break; case SPR_BKEY: // Blue Key star_api_add_inventory_item("blue_key", "Blue Key", "..."); break; } } // Check if player already has a key (e.g. carried over from Our World) if (star_api_has_item("golden_key")) { door_open(GOLDEN_DOOR); // a door that only OQuake players can find the key for }
Step 5 — Quest Chain (ODOOM → OQuake → Our World)
// Complete quest objective 0 of the Key Hunters Trilogy // (collecting the Crimson Key advances the cross-game quest) star_api_complete_quest_objective(KEY_HUNTERS_QUEST_ID, 0, avatar_id); // Query quest progress for HUD display star_api_quest_progress_t prog; star_api_get_quest_progress(KEY_HUNTERS_QUEST_ID, avatar_id, &prog); HU_DrawQuestProgress(prog.completed_missions, prog.total_missions);
ODOOM game code: UZDoom fork ↗ · OASIS ODOOM integration: OASIS Omniverse/ODOOM ↗ · OGLib: OASIS Omniverse/OGLib ↗ · OGEngine Client: OGEngine Client ↗