Skip to content

Osrs env upstream#500

Open
valtterivalo wants to merge 18 commits intoPufferAI:4.0from
valtterivalo:osrs-env-upstream
Open

Osrs env upstream#500
valtterivalo wants to merge 18 commits intoPufferAI:4.0from
valtterivalo:osrs-env-upstream

Conversation

@valtterivalo
Copy link
Copy Markdown

@valtterivalo valtterivalo commented Mar 15, 2026

three (currently) OSRS environments (or encounters as i call them inside this broader OSRS env) in pure C. the env itself and its backend has a ton of OSRS logic already that supports building new encounters pretty easily, but abstractions for this could be way better. we'll see where that goes naturally after we start implementing more encounters. ofc i'd rather have the entire damn playable game as a single functional environment but let's be honest about the amount of work involved.

osrs_pvp: NH PvP with 24 scripted opponents (trivial to onetick+action-reading), PFSP support, 7-head discrete action space (39 logits), 373-dim obs. full combat: gear switching, prayers, eating, specs, movement, action masking. most complete encounter here, but some bugs might remain (or have been introduced lately from abstracting things away to env level).

osrs_zulrah (WIP): money snek solo boss encounter, trying to be as faithful as possible to the real deal but some work remains with more ambiguous mechanics. 3 gear tiers with all special effects etc covered (tbow scaling, sang heal, crystal set bonus, eye of ayak magic drain, confliction double-roll, thralls). basic reward shaping for training, i couldn't get budget setup to win without shaping. bis gear obviously shits on the snake with no problems.

osrs_inferno (WIP): the full inferno challenge encounter with all the waves and the final boss. current dev work has still been basic sim rigor, also prompted me to abstract away a shit ton of stuff so that future encounters are easier to implement. assets are mostly good but some animations and projectiles need to be wired up. NPC mechanics are coming together. RL training isn't yet stable and i didn't run any sweeps yet. probably a couple more days of basic sim work and then back to training models!

binary data assets (sprites, models, collision maps) gitignored, regenerated from OSRS cache via included python scripts that are pretty easy to read and understand. expect there to be quite a bit of coordinate system flipping and offset trial and error when implementing new areas and encounters, but that's part of the deal until we figure out something rigorous for that.

image image image

@valtterivalo
Copy link
Copy Markdown
Author

added inferno, WIP ofc

@valtterivalo valtterivalo force-pushed the osrs-env-upstream branch 2 times, most recently from b941b46 to caa7375 Compare April 7, 2026 09:09
@valtterivalo
Copy link
Copy Markdown
Author

quite a bit of refactoring in the above commit, trying to make adding encounters as easy as possible for other devs. some straight up inferno work in there too

shared sim headers in src/osrs/, per-encounter bindings in ocean/osrs_*/,
visual viewer + asset export pipeline in ocean/osrs/. build.sh wired up
with -Isrc/osrs for osrs_* envs.
visual builds (--local/--fast/--web) auto-download pre-exported assets
from GitHub releases. training builds need no assets. OSRS visual binary
uses shared ocean/osrs/osrs_visual.c source.
env_name must match build dir name (osrs_inferno not puffer_osrs_inferno)
or pufferl.py _resolve_backend assertion fails. test build instructions
updated for src/osrs/ header location. removed legacy export_inferno_npcs.py
(superseded by tools/export_encounter_npcs.py) and standalone Makefile
(build.sh --local handles visual builds).
c_render now calls pvp_render in all three envs so puffer eval --render-mode
raylib actually renders. forward-declare pvp_render in osrs_pvp_api.h so
bindings can opt into render by including osrs_render.h. fix PvP binding
to use current pvp_runtime/ocean_io struct layout (was using flat fields).
render.h and encounter headers define static helpers only called by
the standalone viewer. wrap render/encounter includes in GCC diagnostic
push/pop to silence unused-function noise in the binding compile.
osrs_visual.c loads from relative 'data/' path. binary runs from repo
root where build.sh outputs it, so data/ needs to be there too.
keep env-specific code under ocean/ alongside the visual viewer and
scripts. build.sh points -Iocean/osrs at them. also always download
visual assets, not just for --local builds, since puffer eval renders
through the same _C.so and needs them present.
valtterivalo and others added 11 commits April 12, 2026 22:22
- c_render now loads encounter terrain/objects/models/anims on first call
  (same as standalone viewer did in run_visual), so puffer eval renders
  the 3D world instead of a black screen
- middle-mouse pan was inverted (mouse right → world left); fixed sign
- prayer/spell sprite filenames now numeric (matches what osrs_gui.h
  loads). also point build.sh at osrs-assets-v3 which includes missing
  hitmarks and headicons_prayer sprites
c_render now sleeps between frames to match ticks_per_second so eval
runs at OSRS speed instead of blazing through. 9/0 keys adjust the
speed during viewing (uses the same existing mechanism standalone
viewer already had).

also fix: clicking ground while a spell is selected now walks to that
tile AND cancels targeting, matching OSRS behaviour. previously it
just silently cancelled without walking.
- window now 765x503 matching OSRS fixed-client layout, side panel 190px.
  tile grid decoupled from pixel size (was tied together, forcing wide
  viewport). inventory cells scaled from 76x65 down to OSRS-native 42x36.
- inferno ammo slot items (dragon darts, dragon arrows) no longer appear
  as swappable inventory stacks. in real OSRS darts live in the blowpipe
  and arrows in dizana's quiver, not as separate inventory items.
- add bastion potion and stamina potion inventory slot types with proper
  OSRS item IDs (22461/22464/22467/22470 and 12625/12627/12629/12631).
  inferno was previously rendering these as super combat + ranging pot
  because the generic slot types were reused.
wraps ExportItemSprites.java with auto-download of runelite-cache and
transitive deps from Maven Central / RuneLite repo. first run downloads
~13MB of jars into ocean/osrs/build/item_exporter/deps/, subsequent
runs reuse them. requires java 11+ and curl.

export_all.sh now calls it for the default loadout items (inferno pots,
darts, arrows, weapons). skips gracefully if javac not installed.

also bump osrs-assets release to v4 which includes the dragon dart,
bastion potion, and stamina potion item sprites.
add yellow border on the selected spell cell while in spell-target
cursor mode (clicked a spell, waiting for enemy click). record the
exact GuiSpellIdx clicked so highlight shows the right cell (was only
storing ATTACK_ICE/ATTACK_BLOOD family).

also fix ancient spellbook row ordering: real OSRS goes Rush -> Blitz
-> Burst -> Barrage left to right (ascending level), and Blood above
Ice. was previously Rush/Burst/Blitz/Barrage which is wrong.
set PLAY_REPLAY=path.replay and the first env (env 0) loads the replay,
seeds the encounter RNG to match the recording, and overrides the
policy's actions with the recorded ones every tick. other envs run the
policy as normal. combine with RECORD_REPLAY in training to first save a
best episode, then PLAY_REPLAY in eval to watch it back.
prayer book: now 29 entries in 5x6 grid matching real OSRS display order
(by level, Prayerbook widget layout). sprite IDs corrected — each prayer
now shows its actual sprite (SharpEye was showing as RockSkin etc).
added Mystic Lore, Steel Skin, Ultimate Strength, Incredible Reflexes
that were missing from the 25-entry grid.

ancient spellbook: now the full 4x4 combat grid + vengeance, sorted by
level (Rush/Burst/Blitz/Barrage rows, Smoke/Shadow/Blood/Ice cols).
non-castable spells (Smoke/Shadow) render with the greyed 'off' sprite
for authenticity; clicks on them are ignored. only Ice/Blood/Vengeance
enter the targeting flow.

attack styles: weapon-specific names — bow/blowpipe/zcb shows 3 buttons
(Accurate/Rapid/Longrange), scythe shows 3 (Chop/Jab/Block), godsword
shows Chop/Slash/Smash/Block, claws shows Chop/Slash/Lunge/Block, staff
shows Bash/Pound/Focus/Block. unknown weapons fall back to the classic
Accurate/Aggressive/Controlled/Defensive.
export_sprites_modern.py now writes all 32 ancient spell sprites
(smoke, shadow, blood, ice × rush/burst/blitz/barrage × on/off) so
the full ancient spellbook renders correctly.
…indow

three fixes for puffer eval that the standalone viewer didn't have:

1. c_render bootstrap: lazy-init in c_render now mirrors the standalone's
   run_visual sequence after first pvp_render — load equipment models +
   anims, init overlay models, load encounter terrain/objects/cmap/anims,
   call render_populate_entities to set arena bounds, then re-center the
   camera on the arena and seed sub-tile positions for entities. without
   this the camera stayed at default wilderness coords and the 3D world
   rendered as a black void even though assets loaded.

2. tick pacing: c_step now sleeps to match ticks_per_second (default
   1.667 = OSRS native 600ms/tick) so eval doesn't blaze through episodes
   at Python rollout speed. 9/0 keys still adjust the rate live via
   render_handle_input. only paces when rendering is active (rc != NULL).

3. window 1.5x: 765x503 → 1148x755 with proportional 285px panel and
   63x54 inventory cells. same OSRS aspect ratio, comfortable on modern
   monitors.
remove separate osrs_inferno_zuk.ini alias — use --env.start-wave 69
instead. update window size comments to reflect the 1.5x scaling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants