* show weight instead of size in loot dialog
* chore: auto-format with clang-format
* added configuration
* chore: auto-format with clang-format
* added percentage mode only
* chore: auto-format with clang-format
* use percentage for simple indiator in containers, remove the percentage mode only, change default to simple indicator
* Update src/settings.h
typo
Co-authored-by: Mike Klaas <mike.klaas@gmail.com>
* changed the threshold to be applicable only to the containers and se it to 50%.. changed the colors for the weight indicator and the party member name in the loot dialog.. also tweaked label position for bigger critters like Marcus
* restore font to the previous value in case threshold filters out the indicator
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* missing leading space in weight indicator comments in fallout2.cfg
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* use actual runtime value of the size of the columns instead of trusting the setting value
Co-authored-by: Mike Klaas <mike.klaas@gmail.com>
* minor reformulation of the comments in fallout2.cfg
Co-authored-by: Mike Klaas <mike.klaas@gmail.com>
* explicitly use std::ceil() over ceil() to follow convention in this file and to make copilot happy
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Mike Klaas <mike.klaas@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* change HitMode, HitLocation, CriticalHitDescriptionDataMember and CombatBatShot to its respective underlying integer types and enforce enum usage in the functions
* chore: auto-format with clang-format
* renamed CriticalHitDescriptionDataMember to CriticalHitDataMember. implemented isValid functions for the refactored enums in combat_defs.h. created template function for getting validated enum value in interpreter.h.. used isValid enum functions around the place
* chore: auto-format with clang-format
* changed gCombatState from uint handling to bit flags enum
* chore: auto-format with clang-format
* remove unused valid/interpreter method for CombatBadShot
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
For some RPU elevator transitions, I was seeing the screen partially not update. This was due to rejecting the setCenterTile due scroll blockers (I think). This turns those off if EDG support is enabled.
This also seems to fix some of the jittery scrolling I was seeing in diagonal areas like SF
* Fix elevator cancelation in RPU
If you step into an elevator in RPU and cancel the floor selection, the door closes behind you (sometimes with glitchy graphics). This is a latent bug in the elevators code that vanilla doesn't hit
- elevator_select_ mutates the caller’s elevation to a UI/display level before the modal loop.
- Escape/cancel returns 0 without writing a destination tile.
- Caller then sees map == current map and elevation != current elevation, so it closes the nearby door.
- tile is still -1.
* NovaRains approach
* dont default to first floor if not found
* We call skillGetValue(gDude, SKILL_SNEAK) for every target
* For non-critters, that can result in OOB memory reads
* We only need it for gDude for sneaking
So let's only call it when dude is sneaking and is the target
* Fix out-of-bounds write in wmWorldMap_load when numCities exceeds wmMaxAreaNum
* use ENTRANCE_LIST_CAPACITY to properly isolate city entrances
And read a rest to dummy struct
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* adds debug print warning regarding extra data in .sav
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Correct `get_object_data` indexes
Currently they are raw offset pointers. This does not work with CE since pointers are wide (64bit) on some (most) platforms. So, we can treat these offsets like constants and return the appropriate fields instead.
There are already used for the most part as enum constants:
* Sfall fix for > 160 maps for automap code (RPU triggers this)
* Logic fix for action menu, where actionIndex was incremented unconditionally and could go out of bounds. This was a regression from vanilla
Add equipment slots to the companion loot screen.
Items can be equipped directly from player or companion inventory. This also allows switching between party members so you can manage all companion's inventories easily. Does not allow equipping items that would otherwise be disallowed.
Also:
Calls HOOK_UNWIELD when adding/removing equipment, meaning mods like npc armor work
Uses HOOK_CANUSE for weapon use checks
Ctrl-click to equip is not implemented since it already transfers items between the two inventories. I tried making it work only for equippable items (and otherwise transfer), but that felt awkward and random. Ctrl-click unequip is implemented.
* handle unimplemented fs_copy/fs_create/fs_find more gracefully from the script point of view
* chore: auto-format with clang-format
* moved to sfall_opcodes
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add offset tracking to --scan-unimplemented
* Add a bunch of missing opcodes
* Hardcode a list of implemented hooks to avoid filtering a long list of hooks that are already done
* Add tracking of specific offsets accessed in unsafe scripting so we can plan replacements
Sample output
```
OFFSET write_int (0x81d1 - 0x1d1 - 465):
0x5190f8 (5345528):
- ./mods/InventoryFilter.dat/scripts/gl_InvenFilter_debug.int
- ./mods/InventoryFilter.dat/scripts/release_gl_InvenFilter.int
0x59e95c (5892444):
- ./mods/InventoryFilter.dat/scripts/gl_InvenFilter_debug.int
- ./mods/InventoryFilter.dat/scripts/release_gl_InvenFilter.int
```
Then we can corrlated it with source:
```
// 0x5190F8 curr_rot
static int gInventoryWindowDudeRotation = 0;
```
* PR feedback
* Grow ability for `ce-dat-tool` to extract a list of files
This is needed for Et Tu installation, which selectively extracts files from fo1's master.dat. (It doesn't work if everything is extracted)
* cache entry list to avoid O(n) cost when extracting many files
Currently it isn't playing at all, since we're not doing renderPresent() during the animation loop.
This fixes that. Also, it optimizes the time the animation takes by starting it before the interface combat start/end animation. This saves half a second or so.
* Remove hidden items when trading with Goris
Also, fix the fix to allow looting with Goris
This adds major simplification and deduplication to inventory.cc, including the start of an "InventoryScroller" class that can manage inventory events without duplicate handling everywhere. This is needed as we add more complexity to the page.
* Fix crash due to corrupted `whoHitMe`
It's possible for some object's `whoHitMe` to contain `-1`. It's supposed to be resolved to `nullptr`, but doesn't reliably happen in all cases, esp outside of combat. The main fix here is to normalize to nullptr when loading the object, instead of just map load, or combat paths.
At some point I thought the problem might have been attacker being a non-critter. Added some guards against that regardless. Also, found several bugs and messiness in `apply_damage` which are now fixed.
Fixes https://github.com/alexbatalov/fallout2-ce/issues/368
* Fix ddraw.ini -> game.cfg migration on unix-y systems
We were using `compat_splitpath` on a windows path. We want to work on windows paths, so that's good. This fixes compat_splitpath so that it works with both folder separators. Also tweak `compat_makepath` to recognize both, for consistency.
This means that filenames with `\` will be broken, but I think we can (and should) live with that)
* Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* chore: auto-format with clang-format
* fix
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Better fix for directory detection
A couple places we used compat_file_exists to distinguish between files and folders/dirs, but this breaks on POSIX. This attempts to fix it more holistically
* Make compat_file_exists to be consistent
All platforms now return false for folders/dirs
* Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Most are of this type
```
warning: 'size' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
sfall_arrays.cc:313:26: note: overridden virtual function is here
313 | virtual ProgramValue GetArrayKey(int index, Program* program) = 0;
|
```
* Change `use_walk_distance` to match sfall setting
It's pointless to set this to 0,1 because you don't move if the target is adjacent or yourself, so sfall changes this to "number of spaces" between player and target. We were reading the old ddraw.ini setting before, incorrectly.
Also add a small optimization to not compute path for adjacent targets
* add comment
* return true when distance is self/adjacent
Similar to HRP/Sfall, except:
Does not support non-aspect-ratio-preserving scale mode
Uses vanilla art if it fits without scaling (e.g. 640x480 or non-scaling res like 800x480). The scaled-down HR assets looks considerably worse.
* Bundle Sfall's gl_highlight.ssl
Most mods/distributions assume this is exists since it is bundled with Sfall. It's also a highly requested feature
I decided to merge this as a first-class game config instead of continuing to read mods/sfall-mods.ini. I think most people to this to be a default capability that can be toggled in-engine. Open to other thoughts on the matter. Lost of people will already have sfall-mods.ini configured, which is a reason to keep it the way it was.
* PR feedback
* Fix aiPacketRead overwriting packet_num from savegames, leading to corrupted state on subsequent loads and crash
* Mark variable as unused and add comment
* Change output sound buffer to 44.1 kHz
This allow CE to play 44.1 kHz input files without loss of precision. In particular, it plays HQ music that ships with RPU.
There is a very similar fix in Sfall
* use generic sound loading path to allow .ogg/.wav music files
* rm a few dangling references
* PR feedback
* rm references to audio file
* rm audio_file.cc/h
* restore default audio io
* PR fixes
* Implement `set_unique_id`
* save/load watermark, including compat with previous saves (would be `0`)
* metarule to set and reset unique_id
* inventory stacking rules
* HRP's edg file support (WIP)
* Update docs and fix bug
* chore: auto-format with clang-format
* EDG: proper scroll blocking based on pre-calculated rects, exactly as in HRP
* chore: auto-format with clang-format
* EDG: fix scrolling past pixel-space bounds with sub-hex map edge mod
* EDG: review fixes
* EDG: proper edge clipping matching HRP logic
* chore: auto-format with clang-format
* EDG: code review fixes and refactoring
* chore: auto-format with clang-format
* EDG: fix clamping
* EDG: show arrow cursor and block events when over clipped area
* chore: auto-format with clang-format
* EDG: option to disable
* EDG: deobfuscate code
* chore: auto-format with clang-format
* EDG: get rid of rect2 and simplify algebra
* EDG: update docs, clarify that squareRect is not implemented
* EDG: square mask support
* chore: auto-format with clang-format
* Code review fixes
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bring CE much closer to sfall's load order, and fixes RPU install.
master_patches > critter_patches > mods_order.txt > PatchFileXX > patchXXX.dat > sfall.dat > critter_dat > f2_res_patches > f2_res_dat > master_dat
Also fixed typo in `showMessageBox`, and added a debugPrint in that function, so errors are visible in the log (LLMs otherwise find it hard to figure out what happened)
* Add "trade/loot" context menu for party members.
This was an idea I saw listed on NMA. Veterans of classic Fallout know you can trade with your companions much more easily using the steal skill, But this would be difficult for most new players to discover. This replaces the dialogue option in the long press (which is redundant since it is the default action) with the hand, which is normally used to loot from containers and corpses.
This does introduce a slight inconsistency in the default action, not being present when you long press. how almost everyone will be single-clicking to talk to NPCs.
Also, "you plant..." and "you steal..." messages when trading with companions this way. Put this behind the same flag in case someone wants the original experience.
* Full context menu
* container -> target
* PR feedback
* rebase on main
* rename function
* Add original symbol beside all function offsets
e.g.
```
// 0x414E98 register_object_call
int animationRegisterCallback(
// 0x414E20 register_object_must_erase
int animationRegisterHideObjectForced(
```
This was programmatically generated so there could be errors. Spot checking looks pretty good though
* Mapper: fixed playmode, added some mapper features
* mapper: save map corrections + some stubs
* mapper: fix playmode and cleanup discrepancy
* mapper: edit_mapper inacuracies and tidying up some code
* mapper: corrected Delete Spatial, minor fixes
* mapper: implement debug.show_tile_num, Mark Exit Grid, toolbar name drawing fix and refactoring
* chore: auto-format with clang-format
* mapper: fix inaccuracies after AI review, round 1
* mapper: fix inaccuracies after AI review, round 2
* chore: auto-format with clang-format
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* [HRP] Enable HR dialog screen
(It's not really "hi resolution", just adds a border so it looks less funny.)
Also, picked up @NovaRain's suggestion of centering dialog on the play area if it is large enough, which matches Sfall.
Very simple party barter support. Builds upon the loot screen so is very little code:
Switch party members with left/right arrow keys
When leaving barter with items on the table (canceling), all items go to the PC's inventory
No special handling of money (yet)
The mod pins the player's money stack on top of the inventory list for all party members. That's nice, but also feels a little odd, but likely just because I'm used to the money stack being stuck at bottom. We can iterate on that.
Adding an interface will require art. I considered enabling mouse use triggered by clicking on the avatar which would be quite simple.
* Speed up Fallout1 .dat reader
It was reallocating a buffer on a loop, which caused large files to take minutes. Fixing this reduced it to a reasonable time, but still ~120s for the entire Fallout1 master.dat.
Also, bump the F2 gzip buffer to 4kB. It was only 400 bytes
In 8b2ead8a2b, soundLoad started honoring AudioFileInfo.channels, but the ACM decoder path historically only propagated sample rate. This changes playback in a way that caused the bug.
Verified by talking to good ol' Sulik
* Add support for new talking heads
Add [Heads] config section in ddraw.ini that maps critter PIDs to talking
head indices in art\heads\heads.lst. When a dialog script starts with
headId=-1, the engine now checks the critter proto's headFid first, then
falls back to the [Heads] mapping. This lets mods add talking heads
without patching dialog scripts.
Includes Cassidy mapping (PID 16777305 → head index 13) for use with
cassidy_head.dat mod.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Implement HOOK_INVENWIELD, HOOK_CANUSEWEAPON and fix HOOK_ADJUSTFID
Wire the sfall hooks that npc_armor.mod relies on so party-member sprites
actually change when armor is equipped:
- HOOK_INVENWIELD fires from inventoryEquipFunc/inventoryUnequipFunc with
(critter, item, slot, isWield). Script may veto by returning 0. Slot
values mirror interpreter_extra.cc: WORN=0, RIGHT_HAND=1, LEFT_HAND=2.
- HOOK_CANUSEWEAPON fires from _ai_search_inven_weap so the mod's
weapon-anim restriction can veto AI weapon picks.
- HOOK_ADJUSTFID arg list corrected to match sfall (single currFid arg,
critter resolved via dude_obj).
- ProgramValue::isEmpty no longer treats string values as empty — sfall
scripts like npc_armor's `while (sect.PID)` loop depend on a non-empty
string being truthy.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* enum class
* chore: auto-format with clang-format
* bad merge
* PR feedback
* restore isEmpty() to vanilla while fixing bug
* fixes
* minor fixes
* extra
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: tectiv3 <tectiv3@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Sfall-like sound system
(I would like a better name for this system, but the opcodes themselves are called `play|stop_sfall_sound` and I can't think of a better name)
This is a sound management system very similar to Sfall's. With a few differences:
* No support for new sound formats yet. Support for at least ogg+wav will come next
* Does support reading from .dat files, hence playing any sound effect in the base game
* Support mode=3 for speech volume. This exists in Sfall but is ignored when called from the opcode.
Also, change GaplessMusic to use this system to play the "wind2" loading sound. This restores the "vanilla" feel map transitions, so I think it's reasonable to make GaplessMusic=1 the default. I can't imagine someone wanting to change it to 0 unless they are ultra purists
* Sfall saved arrays support
* Add "...all_arrays..." special case for a list of saved arrays
* Adjust error message on load fail
* Fix crash in GetArrayKey when index == size
* chore: auto-format with clang-format
* Update sfall compatibility md
* Add keyIndex for Assoc Arrays for O(1) key lookups
* Review feedback, more error logging
* Fix build, increase ARRAY_MAX_STRING to 1024 to match sfall, fix gl_test_arrays triggering dynamic string block merge failure, prevent potential string buffer corruption on very long strings
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* iOS: add touch gestures, HUD tap-through, quick-actions toolbar
Makes fallout2-ce playable on iPad without a keyboard, while leaving
non-iOS builds unchanged (all additions are TARGET_OS_IOS-guarded).
Touch gestures (src/mouse.cc):
- 3-finger swipe down → ESC
- 4-finger long-press → F6 (quicksave)
- 3-finger long-press → hold LShift (FO2tweaks highlighting). Uses
SDL_PushEvent so sfall's SDL_GetKeyboardState-based key_pressed()
sees the held key, not just the engine's own kb state.
HUD ergonomics (src/mouse.cc):
- Taps on interface-bar buttons inject the button's keyCode directly
so the cursor stays put. Taps on belt chrome are consumed rather
than teleporting the cursor to inert pixels.
- Two-finger taps on belt buttons → right-click handler.
Gameplay cursor (src/game_mouse.cc):
- On iPad, keep GAME_MOUSE_MODE_MOVE in relative (trackpad) mode so
screen taps don't teleport the cursor during combat. UI screens
that explicitly enable touchscreen mode are unaffected.
Quick-actions toolbar (src/platform/ios/quick_toolbar.{cc,h}):
- Optional iOS-only HUD strip above the belt with skill shortcuts
and end-turn. Header provides no-op stubs for non-iOS builds so
interface.cc can call it unconditionally.
- game.cc refactor: skilldex result handling factored into
gameHandleSkilldexResult() so the toolbar and the keyboard
shortcut share one path.
README: iPad controls section.
* iOS: add quick toolbar visibility preference
Adds a ui.quick_toolbar_visible config flag (default true)
* iOS: skip HUD tap-through when interface bar is hidden
When the interface bar window is hidden (e.g. on the world map),
windowGetRect still returns its rect, causing taps in that screen
area to be consumed as overHud even though there's nothing to interact
with. Check WINDOW_HIDDEN before treating the rect as active HUD.
Addresses Copilot review comment on PR #377.
* iOS: fix dialog options near bottom unclickable on iPad
Enable touchscreen mode for dialog UI so taps reach dialog option
buttons directly. The HUD tap interception in mouse.cc was consuming
taps that landed inside the interface bar rect, even when a dialog
window overlapped that region. Dialog options near the bottom of the
screen were silently swallowed by the belt chrome catch-all.
Skip HUD tap interception when touchscreen mode is active, since a UI
screen (dialog, inventory, skilldex, etc.) owns input in that state.
Add touch_get_touchscreen_mode() getter to support the check.
* iOS: add pipboy touch exception
* Apply fixes from review
* Change quick toolbar default visibility to false
* Add touch mode to character selector
update readme and simplify switch condition
* Implement HOOK_RESTTIMER
Et tu + other mods use this
* PR comments + missing doc for ce-dat-tool
* chore: auto-format with clang-format
* document timer wrap
* cleanups
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Expanded barter window from sfall
* Refactor: FrmImage class to lock based on file name, refactor code from last commit
* Soft limit on named art cache size
* Support localized paths for art loaded by name
* Fix visual issue from original sfall implementation where barter window were scrolling down incorrectly + bufToBuf const correctness
* Fix build error and extra destructor call when adding NamedCacheEntry
* Review fixes
* Update src/art.cc
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Review issues fixed, window made transparent to remove black area below the overlap during scroll down
* chore: auto-format with clang-format
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* `--dev-load-game` commandline arg
This allows you to use --dev-load-game=SLOTXX` to immediately load a saved game after the game is launched. This is mostly useful so that LLMs can launch the game and see the result of an .ssl test script without a human needing to be in the loop
* Extended AP bar from sfall
* Rewrote using new Buffer2D and blitBuffer2D + code review fixes
* chore: auto-format with clang-format
* Add ConstBuffer2D + other fixes
* chore: auto-format with clang-format
* Linux build fix attempt
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add basic content config structure
* Moved non-file related settings from ddraw.ini to game.cfg
* Various fixes from self review
* Moved remaining worldmap settings to game.cfg
* Migrate character and text related settings
* Update docs
* chore: auto-format with clang-format
* Add hard-coded foce_base.dat to have reliable location to load CE-provided content from
* Move game.cfg to new base mod
* Automatic migration from ddraw.ini
* chore: auto-format with clang-format
* Removed option to disable cities limit fix
* Minor review comment fixes
* Migrate to /data instead of CE dat
* Migrate to local game#patch.cfg and skip fields with default values
- This was if some mod modifies/overwrites game.cfg later, only fields that user cares about will be loaded from user's override, and said mod is less likely to break
* Fix potential issue when "master_patches" is an absolute path and move recursive mkdir into a helper function
* Refactor code and fix some edge cases: data folder not exists when migrating, ddraw.ini doesn't exist
* Rename face_base.dat -> ce.dat
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* `set/remove_script` and `HOOK_STDPROCEDURE{_END}`
These were implemented together as I thought HOOK_STDPROCEDURE would be useful for testing set_script.
* Implement HOOK_CALCAPCOST
An opcode a day keeps the stimpak away.
https://sfall-team.github.io/sfall/hook-types/#calcapcost
Same as Sfall, but also calls the hook on game load to display the correct AP cost on load.
Also fix a minor bug where the attack mode of the current hand sometimes leaked when loading a save game. Normally attack mode (burst/reload/&c) isn't saved. But if you are in aimed mode (say), and load a game with the same weapon equipped, the attack mode will persist. This is pretty weird, so changed it to always be in the default mode when loading a save.
* test script
* PR comments
* doc tweaks
* Retain key§ions comments when overwriting fallout2.cfg
- Vibe coded with human review and testing
* Fix anim_speed key name
* Revert comment removal by Gemini
* Handle final remove/rename failures
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix edge case when filePath is near MAX_PATH
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove dead weight
* Vibe coded bug fixes and new write flag
* Comment for config flags
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix garbled splash screen when `SkipOpeningMovies=1`
If the splash screen is shown but movies are skipped, the main menu palette is applied to the splash screen for a split second, showing garbled colours. This doesn't happen with movies since they clear the screen.
Fix is to force a black screen clear beforing fading in the main menu
* simplify
* chore: auto-format with clang-format
* Restore palette before load-list error dialog
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Implement sfall `signal_close_game`
Used by Et tu, but might be useful for LLMs too to quit the game after running a test case.
Also added enum for `_user_wants_to_quit`, and did minor reformatting of SFALL_COMPATIBILITY.md
* Moved f2_res.ini settings into regular game config
* Rename resolution fields
* chore: auto-format with clang-format
* Code review fixes
* chore: auto-format with clang-format
* One-time migration of f2_res.ini to fallout2.cfg (#350)
* One-time migration of f2_res.ini to fallout2.cfg
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Mike Klaas <mike.klaas@gmail.com>
Saw a crash while testing gl_ShowLootWeight. The issue was that the script uses `repeat(1)`, and we tried to spawn it again while it was running.
The fix is to check if the program is already running, using the same logic as the game does when running scripts.
This doesn't happen with Sfall since its global script implementation is more integrated with the interpreter. This does point to likely other subtle differences that might matter.
* Deobfuscation pass for interpreter.cc/h
Almost entirely mechanical renaming, with very minor semantic changes:
* changed a couple globals to `static` which were only in this file
* changed a couple bool-like ints to bool
* started adding `const` to local vars
* Fix `list_as_array(LIST_CRITTERS)` returning objects with pid=-1
When using gl_highlighting, I saw:
```
2026-04-01 12:42:52.824 Fallout II Community Edition[34437:20111056] INFO: Current script: scripts\gl_highlighting.int, procedure ToggleHighlight
2026-04-01 12:42:52.950 Fallout II Community Edition[34437:20111056] INFO: Script Error: scripts\gl_highlighting.int: op_critter_state: obj is NULL
2026-04-01 12:42:52.950 Fallout II Community Edition[34437:20111056] INFO:
Error during execution: get_proto_data: bad proto -1
```
We missed checking that pidType < -1, so we indexed kObjectTypeToListType[-1] which is UB. Either we were lucky and this OOB memory matched, or the compiler was getting cheeky. This fixes the bug and stops the error.
* PR feedback
I did this as part of looking into `WorldMapSlots=21` support. I don't fully understand that one yet, but this semantics preserving cleanup is worth committing
* Fix global script loading on non-Windows
Previously, global scripts in .dats and in local FS didn't work due to path separator confusion.
Now:
* Hardcode global script path to "scripts\gl*.int" (windows separator)
* Use Windows fpattern matching inside of dFile (.dats, which always use windows separators)
* Use \-paths when listing found global scripts
The awkward part is having to vendor a copy of fpattern to force it to use "windows mode". It's possible that we could use this everywhere since windows allows / as separator, but that could cause bugs where we're using fpattern on the native FS. For now keeping the dFile implementation separate makes sense.
The idea is that modders / contributors could track what is implemented, what is planned/unplanned, &c. There's a risk that we won't keep it up to date, but I think it's a document that we'll need eventually.
* Barter hook refactor: weight compute in separate fn, names and comments for related vars, consistent value args
* Hook scripts: use initializer_list for defining args
* Keypress Hook: don't trigger on repeat, to match sfall
* chore: auto-format with clang-format
* Attempt to fix formatting after clang-format
* Don't use references for return values, for better readability
* chore: auto-format with clang-format
* Code review fixes
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
https://sfall-team.github.io/sfall/sfall-funcx-macros/#add_extra_msg_file
For now we're choosing to not support the 2-arg form. We could return `-1` if the script tries to do this, but if so and it doesn't check for an error, that's likely worse than just crashing at this point. It's essentially an unimplemented opcode.
* Deobfuscate `scripts.cc/h`
Mostly renaming, but also includes:
* Some straightforward uninling
* Function extraction of a pretty large chunk (elevators)
* Simplification of the script loading loop
Tested manually
* hooks: an empty cc and a list of hook types with useful comments
* Deobfuscate some script-related procedures and flags
* Script hooks WIP
* Interpreter: add programPrintError(), Program->procedureCount(), rename string-related functions
* ScriptHookCall refactoring and all basic hook script opcode implementation
* HOOK_KEYPRESS and first working hooks
* mf_obj_under_cursor + some test script
* HOOK_TOHIT
* chore: auto-format with clang-format
* Add hooks: useobj, useobjon
* chore: auto-format with clang-format
* opcode: get_sfall_args
* Code review fixes
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Deobfuscations of draw,endgame,interface,preferences
This is _mostly_ mechanical renames.
There are a few other changes:
* Extracted two helper functions
* Added a couple constants that virtually eliminated "magic numbers" in a couple functions
* Switched one int -> bool
* Made sure interfaceGetCurrentHand() is compared against HAND_RIGHT/LEFT instead of treated as boolean
* comment dev by zero issues
* Rename window* -> scriptWindow*
This disambiguates the function names from those in managed_window.cc (which also used window*)
Plus a few items of PR feedback from https://github.com/fallout2-ce/fallout2-ce/pull/286
* Rename functions with RE-based names for consistency with new scheme
* Rename sub_* that have equivalents in original source
sub_* names pulled from https://raw.githubusercontent.com/sfall-team/sfall/master/sfall/FalloutEngine/FunctionOffsets_def.h if possible
Per discussion in Discord, sticking with camelCase names
* build fix
* window*
* Rename several more window* functions, add explanatory comment
---------
Co-authored-by: phobos2077 <phobos2077@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Vlad K <phobos2077@users.noreply.github.com>
Fallout tries to be smart about walking vs running: if an object you're interacting with is "close" (<5 tiles), the PC will walk, otherwise, they'll run.
The problem with this is that the distance is calculated "as the crow flies" and doesn't take into account the path length. So not rarely, your character will end up slowly walking a long distance to interact with an object.
This PR fixes that by using path length instead of tile distance. This is slightly less performant, but extremely unlikely to ever be noticable. Regardless, I used actual pathfinding only when the tile distance is short, so it is very unlikely to generate long paths (which, in any case, can happen just by trying to move to that tile).
To test, load the given save file. Interacting with things on the other side of the wall usually triggers annoying walk behaviour. E.g.:
* Looting the shelves on the other side of the wall
* Using Steal on the shelves / on an NPC
* Dropping an item on one side then picking it up from the other side.
* Use `FID_ROTATION` macro to remove manual bit shifting
This is a mechanical change.
Note: this uncovered what I'm almost certain is a bug in the interpreter code. I can fix it based on code inspection... this is how it's used everywhere else. I'm not confident about reproducing it in game though, so open to thoughts on how to preceed here.
* Fix bugs
Implements get_ini_section, needed for Et Tu, and get_ini_sections. Fixes buggy set_ini_setting.
Also includes tests for existing ini functions, and moves them all to sfall_init.cc. (opcodes and metarules files were getting long, and this matches sfall's structure)
This pulls in every sfall opcode, including param types and returnval. It is grouped in a more "natural" order (i.e. what the sfall doc lists) instead of numeric order, which helps see which opcodes from a logical group are missing
Implement string_to_case, and add comments for missing metarules/opcodes
string_find
string_compare
charcode
This should complete all string functions listed here that aren't deprecated.
* chore: auto-format with clang-format
* PR feedback
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This removes the creation of a 'dat' folder when opening or path finding fails. This may have been a leftover from development, or part of the mapper, however, in practice it prevents users getting correct error messages when opening the app with missing dats or incorrect dat paths.
With this fix, missing dats or paths should give a popup message to the user, instead of the ubiquitous 'cannot find fonts error'
* Fix bug that stopped music when reloading on the same map
If you have GaplessMusic=1 and load a saved game on the same map you're currently on, we erroneously skip playing music. This fixes that problem.
Also, still playing loading sound if no background music is playing (not sure there can actually happen). I still want to get the loading sound back in eventually.
Finally, added a bit of decyption. It's not complete yet but has some deciphering
* chore: auto-format with clang-format
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add Ctrl-click to move items in inventory, barter, looting/stealing
Barter: move from table (offer) to inventory, on both merchant and pc.
Looting/stealing: move from one side to the other.
Inventory: ctrl-click to unequip armor or item in hand.
Modeled after the SFALL feature.
* skip quantity selection when quick moving
* Add `a` to inventory quantity select screen as a quick way to select ALL
* format
* Add Readme changes, and `a` to `Take All`
* try to format
* fmt
I can't think of a reason why someone would want to do hires without the stencils. Nevertheless it's still turn off-able using `HiResMode=0` if desired.
In addition, updated the Readme to not mention it (since only very few people would care about turning it off), and fixed the link to the sample ddraw.ini
Almost entirely renaming three struct fields of "AnimationSad" (an in-progress movement) and adding constants.
As usual, there are zero functional changes in this PR.
Fixed to make buttons work when clicked, or when using key commands.
This makes an imperfect button sound (misses the click release), however, the game is littered with this compromise.
Fixes#90
Fixed to make buttons work when clicked, or when using key commands.
This makes an imperfect button sound (misses the click release), however, the game is littered with this compromise.
Fixs #88
IIRC, the "unit" for things like 10mm ammo in F1 used to be a dozen (12x).
In F2CE, the unit of ammo seems to be a single round. Prior to this patch,
AI companions (in my case, the Mercenary in Sonora) would reload a single
round into their weapon when they run out, so turns in combat become a loop
of fire, reload, fire, reload, etc.
With this patch, AI reloading keeps inserting ammo into the weapon until
capacity is reached or the critter runs out of ammo.
Increases Load/Save slots to 100 - sFall?
Adds pagination and controls to move between slots - previous scrolling/key functions work as normal, and move between pages
No ini setting yet, code it set up to shift based off a single ini setting.
Issue: if a user skips turn by clicking end a combat turn button
the cursor becomes frozen in "watch" mode but all input events are queued.
If a user clicked while the AI turn is not ended then the next user's turn is skipped.
Fix: clear input queue each time before user's turn.
Looks like clang-format in Ubuntu does not recognize glob pattern as
macOS does. Previous solution without xargs reported status code of
find itself, not clang-format.
Previous solution did not work well on high resolutions due to
incorrect tile calculations - was not updating edges and sometimes
hanged in endless loop trying to find upper-left or bottom-right
tiles.
New solution follows Sfall's HRP implementation.
Previous solution to replace squares was destructive in nature and
could possibly lead to unexpected things (especially with mods where
tile 0x293 might not be opaque black).
New solution follows mapper refresh routines where entire dirty rect
is reset to black as a preparation step.
- Better vertical positioning (account for word wrapping)
- Better horizontal positioning (consider both right and left gaps for
calculating available width).
- Prevent vertical text overflow.
<!--- Clearly describe the changes introduced by this PR. What was fixed, added, or updated? --->
### Reproduction Steps and Savefile (if available)
<!--- Provide detailed steps to reproduce the issue. Include a savefile if applicable, preferrably for Sonora --->
### Screenshots
<!--- If the PR includes visual changes, add screenshots here. --->
<!---
**Important Notes**
- *Preview builds are not available for pull requests from forked repositories.* To enable preview builds, submit the PR from a branch within this repository.
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products Microsoft.VisualStudio.Product.BuildTools -requires Microsoft.VisualStudio.Component.VC.v141.x86.x64 Microsoft.VisualStudio.Component.VC.v141.xp -property installationPath`) do set "VS_PATH=%%i"
call "%VS_PATH%\Common7\Tools\VsDevCmd.bat" ^
&& cmake --preset windows-${{ matrix.arch }}
- name:Build
shell:cmd
run:|
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products Microsoft.VisualStudio.Product.BuildTools -requires Microsoft.VisualStudio.Component.VC.v141.x86.x64 Microsoft.VisualStudio.Component.VC.v141.xp -property installationPath`) do set "VS_PATH=%%i"
`-` can be used to take input from stdin (e.g. from `ce-dat-tool cat`) or write to stdout. When reading from stdin, pass `--from-frm` or `--from-png`. Output defaults to PNG for FRM input and FRM for PNG input when output is omitted or `-`; use `--to-png` for PNG output to stdout from PNG input.
Output file extensions are validated against the selected conversion. For example, PNG-to-FRM output must use `.frm`, and PNG output must use `.png`.
If `--palette` isn't specified, it will pick up `color.pal` in the input file's directory or cwd.
Notes:
- The tool expects a raw `color.pal` file. It does not read palettes directly from `master.dat`, so extract `color.pal` first if needed.
- A typical extraction flow is: `ce-dat-tool master.dat extract --lower . 'color.pal'`
- By default palette index `0` becomes transparent in the output PNG. Pass `--opaque` to keep it opaque.
- PNG output is always palette-indexed and preserves Fallout palette indices when possible.
- For `png -> frm`, transparent pixels (alpha below 128) map to palette index `0` by default. Pass `--opaque` to quantize every pixel instead.
- The current `png -> frm` implementation writes a single-frame FRM and points all six direction slots at the same frame payload.
## Updating SDL
SDL is pinned for native builds in `third_party/sdl2/CMakeLists.txt`. Right now, Android also relies on checked-in Java bindings in `os/android/app/src/main/java/org/libsdl/app`, and those bindings must match the SDL version fetched by CMake.
When updating SDL:
1. Update the SDL tag in `third_party/sdl2/CMakeLists.txt`.
2. Run an Android build once so Gradle/CMake fetch the new SDL source tree.
3. Copy the Android Java bindings from the fetched SDL checkout into `os/android/app/src/main/java/org/libsdl/app`.
4. Rebuild Android and confirm the SDL sync guard passes.
The Android build contains a guard in `os/android/app/build.gradle` that fails if the checked-in Java bindings drift from the fetched native SDL source.
This is a hack, not a good long-term setup. The Java bindings are still duplicated in the repo instead of being sourced from the same SDL tree as the native build. That should be improved so Android does not depend on a manual copy/sync step.
By using the software, you agree to all of the terms and conditions below.
## Copyright License
The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations below.
## Limitations
You may use or modify the software only for your own internal business purposes or for non-commercial or personal use. You may distribute the software or provide it to others only if you do so free of charge for non-commercial purposes. You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law.
## Patents
The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
## Notices
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms. If you modify the software, you must include in any modified copies of the software a prominent notice stating that you have modified the software.
## No Other Rights
These terms do not imply any licenses other than those expressly granted in these terms.
## Termination
If you use the software in violation of these terms, such use is not licensed, and your license will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your license will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your license to terminate automatically and permanently.
## No Liability
As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
## Definitions
The "licensor" is the entity offering these terms.
The "software" is the software the licensor makes available under these terms, including any portion of it.
"You" refers to the individual or entity agreeing to these terms.
"Your company" is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. Control means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
"Your license" is the license granted to you for the software under these terms.
"Use" means anything you do with the software requiring your license.
"Trademark" means trademarks, service marks, and similar rights.
Fallout 2 Community Engine is a fully working re-implementation of the Fallout 2 engine, optimized for a hassle-free experience on multiple platforms, including Windows, Mac, iOS, Android, and Linux. It provides high resolution support, quality-of-life improvements, and dozens upon dozens of bug fixes.
You must own the game to play. Purchase your copy on [GOG](https://www.gog.com/game/fallout_2) or [Steam](https://store.steampowered.com/app/38410). Download latest release or build from source.
This is a fork of the original Fallout2: CE project, which is no longer getting regular updates.
Popular Fallout 2 total conversion mods are partially supported. Nevada and Sonora work. [Fallout 2 Restoration Project](https://github.com/BGforgeNet/Fallout2_Restoration_Project) is supported (in Beta). [Fallout Et Tu](https://github.com/rotators/Fo1in2) and [Olympus 2207](https://olympus2207.com) are not yet supported. Other mods (particularly Resurrection and Yesterday) are not tested.
Fallout2: CE has broad (though not total) compatibility with [Sfall](https://github.com/sfall-team/sfall) scripting extensions. Many traditional Fallout mods work out of the box, including NPC Armor, Party Orders, FO2Tweaks (we recommend v14.5+), Talking Heads, and many others.
## Installation — [Download Latest CE Release](https://github.com/fallout2-ce/fallout2-ce/releases)
You *must* own the game to play. Purchase your copy on [GOG](https://www.gog.com/game/fallout_2), [Epic Games](https://store.epicgames.com/p/fallout-2) or [Steam](https://store.steampowered.com/app/38410).
Download CE from the link above, then extract the archive into your game folder. Launch `fallout2-ce.exe` on Windows (or the platform-specific executable) to play. CE has a lot of enhancements that require configuration. See [Configuration](#configuration) for examples.
For detailed instructions on how to play on Mac, Linux, iOS, or Android, see the [Platform-specific instructions](#platform-specific-installation).
## Quality of life benefits over vanilla Fallout
* High resolution support
* Party members can loot and barter in place of PC
* Directly equip party members instead of convincing them to use the right equipment.
* Expanded 2-column inventory, loot screens
* Expanded 4-row barter screen
* Expanded AP bar
* Ctrl-click to quickly move items when bartering, looting, or stealing, and auto-balance caps
* Music continues playing between maps
* Auto open doors
* Integrated "HELP" menu
* 44.1 kHz stereo sound/music supported, in .ogg and .wav format as well as legacy .acm
* Last used save slot is remembered
* Item/Corpse/Container/Critter highlighting (configure using [mods/sfall-mods.ini](https://github.com/sfall-team/sfall/blob/master/artifacts/config_files/sfall-mods.ini))
<img src="docs/images/party-member-loot.gif" alt="Party member loot" width="360"><br>
<sub>Party member loot</sub>
</td>
<td align="center">
<img src="docs/images/help-menu.gif" alt="Integrated HELP menu" width="360"><br>
<sub>Integrated HELP menu</sub>
</td>
</tr>
</table>
There are also dozens of small things that just work a little better than they did in the original. Better pathfinding, fewer graphics glitches, less finicky weapon stacking, and much more.
## Configuration
The main configuration file is `fallout2.cfg`. This contains original game config as well as new CE settings.
Additional settings for screen resolution, UI customization, and map options are now integrated into the main `fallout2.cfg` file (previously part of `f2_res.ini` from Mash's HRP).
Here are some important settings in `fallout2.cfg` under the `[screen]` and `[ui]` sections. See [the example config](https://github.com/fallout2-ce/fallout2-ce/tree/refs/heads/main/files/fallout2.cfg) for a full list of settings.
```ini
[screen]
resolution_x=1600 ; actual game window size (screen resolution), in pixels
resolution_y=1080
windowed=1 ; 0 = fullscreen
scale=2 ; 1 = original scale, 2 = 2x scale, etc. (e.g. at scale 2 and screen resolution 1920x1080, in-game resolution will be 960x540, thus every pixel is twice as wide and tall)
[ui]
; Maximum number of columns shown in the main inventory and loot/steal windows (valid range: 1..2)
inventory_columns=2
; Set to 1 to expand the barter/trade window vertically, adding a 4th item slot per side (requires ce.dat)
expand_barter_window=1
[qol]
; Allow opening party member inventory from the long-press context menu.
party_trade_from_menu=1
; Allow switching to companions' inventories in loot screens (and barter, in the future)
party_loot_and_barter=1
```
**Recommendations:**
- **Desktops**: Use any size you see fit.
- **Tablets**: Set these values to logical resolution of your device, for example iPad Pro 11 is 1668x2388 (pixels), but its logical resolution is 834x1194 (points).
- **Mobile phones**: Set height to 480, calculate width according to your device screen (aspect) ratio, for example Samsung S21 is 20:9 device, so the width should be 480 * 20 / 9 = 1067.
In time this stuff will receive an in-game interface, right now you have to do it manually. To see all currently working fallout2.cfg settings, just run the game once and quit. It will be automatically updated with defaults for every supported setting.
*Note*: Use of the IFACE_BAR settings requires the `f2_res.dat` file, which contains graphical assets. Various versions are available, but one compatible with the above settings can be found here: [f2_res.dat](https://github.com/fallout2-ce/fallout2-ce/raw/refs/heads/main/files/f2_res.dat)
## Platform-specific installation
### Windows
Download and copy `fallout2-ce.exe` to your `Fallout2` folder. It serves as a drop-in replacement for`fallout2.exe`.
[Download](https://github.com/fallout2-ce/fallout2-ce/releases) and unzip into your `Fallout2` folder. Launch the game using`fallout2-ce.exe`.
### Linux
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder somewhere, for example `/home/john/Desktop/Fallout2`.
- Alternatively you can use Fallout 2 from Macplay/The Omni Group as a base - you need to extract game assets from the original bundle. Mount CD/DMG, right click `Fallout 2` -> `Show Package Contents`, navigate to `Contents/Resources`. Copy `GameData` folder somewhere, for example `/Applications/Fallout2`.
-Download and copy `fallout2-ce.app` to this folder.
-Or if you're a Terminal user and have Homebrew installed you can extract the needed files from the GoG installer. **Note**: You must use "Offline backup game installer", not the main game installer.
- [Download](https://github.com/fallout2-ce/fallout2-ce/releases) and copy `Fallout II Community Edition.app` to this folder.
- Run `Fallout II Community Edition.app`.
### Android
> **NOTE**: Fallout 2 was designed with mouse in mind. There are many controls that require precise cursor positioning, which is not possible with fingers. Current control scheme resembles trackpad usage:
- One finger moves mouse cursor around.
- Tap one finger for left mouse click.
- Tap two fingers for right mouse click (switches mouse cursor mode).
- Move two fingers to scroll current view (map view, worldmap view, inventory scrollers).
> **NOTE**: From Android standpoint release and debug builds are different apps. Both apps require their own copy of game assets and have their own savegames. This is intentional. As a gamer just stick with release version and check for updates.
- Download the Android [release](https://github.com/fallout2-ce/fallout2-ce/releases), which contains an .apk file and `ce.dat`.
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder to your device, for example to `Downloads`. You need `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder. Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)). Copy `ce.dat` into this folder.
- Copy `fallout2-ce.apk` from the release to your device. Open it with file explorer, follow instructions (install from unknown source).
- When you run the game for the first time it will immediately present file picker. Select the folder from the first step. Wait until this data is copied. A loading dialog will appear, just wait for about 30 seconds. If you're installing total conversion mod or localized version with a large number of unpacked resources in `data` folder it can take up to 20 minutes. Once copied, the game will start automatically.
### iOS
> **NOTE**: See Android note on controls.
- Download `fallout2-ce.ipa`. Use sideloading applications ([AltStore](https://altstore.io/) or [Sideloadly](https://sideloadly.io/)) to install it to your device. Alternatively you can always build from source with your own signing certificate.
- Run the game once. You'll see error message saying "Couldn't find/load text fonts". This step is needed for iOS to expose the game via File Sharing feature.
- Use Finder (macOS Catalina and later) or iTunes (Windows and macOS Mojave or earlier) to copy `master.dat`, `critter.dat`, `patch000.dat`, `ce.dat`, and `data` folder to "Fallout 2" app ([how-to](https://support.apple.com/HT210598)). Watch for file names - keep (or make) them lowercased (see [Configuration](#configuration)).
-
**Controls on iPad:**
- One-finger tap → left click; hold → left button held.
- Two-finger tap → right click (cycles cursor mode between walk and attack).
- One-finger drag → scroll map / windows.
- Two-finger drag → mouse wheel.
- **Three-finger swipe down → ESC** (opens options / main menu).
- **Four-finger long press → F6** (quicksave). Hold four fingers on the screen for about half a second.
- **Three-finger long press → hold Shift** (highlights interactable objects — containers, doors, items — while held).
- Taps on the HUD (interface bar / end-turn / end-combat buttons) act as direct touches so small buttons are easy to hit without aiming.
- A Bluetooth keyboard works for everything else (numbered dialog choices, load game, etc.).
### Browser
> **NOTE**: WebAssembly build with emscripten
```
docker run --rm -v $(pwd):/src emscripten/emsdk:3.1.74 sh -c 'git config --global --add safe.directory "*" && mkdir -p build && cd build && emcmake cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/Emscripten.cmake && emmake make'
```
- Demo available at https://github.com/ololoken/fallout2-ce-ems.git
- Run `fallout2-ce.app`.
## Contributing
Integrating Sfall goodies is the top priority. Quality of life updates are OK too. Please no large scale refactorings at this time as we need to reconcile changes from Reference Edition, which will make this process slow and error-prone. In any case open up an issue with your suggestion or to notify other people that something is being worked on.
For build instructions and contributor notes, see [CONTRIBUTING.md](CONTRIBUTING.md).
### Intergrating Sfall
Integrating Sfall goodies is the top priority. Quality of life updates are OK too. In any case open up an issue with your suggestion or to notify other people that something is being worked on.
There are literally hundreds if not thousands of fixes and features in sfall. I guess not all of them are needed in Community Edition, but for the sake of compatibility with big mods out there, let's integrate them all.
For current sfall compatibility status and the remaining work needed to close gaps, see [SFALL_COMPATIBILITY.md](SFALL_COMPATIBILITY.md).
## Legal & License
## For modders
See [Fallout 2 Reference Edition](https://github.com/alexbatalov/fallout2-re). Same conditions apply until the source code in this repository is changed significantly.
* Robust (though not 100%) Sfall opcode and hook support
* .ogg/.wav support for map music
* .png support for static assets (must be 8bit indexed)
* .zip support for .dat archives
* Working BIS mapper
## License
The source code is this repository is available under the [Sustainable Use License](LICENSE.md).
This document tracks Fallout 2 CE compatibility with sfall. This is for modders who need to know which Sfall features work in CE.
For now, this covers opcodes/metarules, and hooks. In the future, it will include other ways of modifying the engine (like ini files), and other Sfall-specific behaviour.
## HRP EDG Scroll-Blocker Support
CE supports the `.edg` file format from the HRP (High Resolution Patch), which defines per-map scroll boundaries and square-level render clipping.
**How it works in CE:**
- On map load, `maps/<mapname>.edg` is read if present. Missing file = silent fallback to the scroll-blocker object system.
- The `.edg` file defines per-elevation rectangle boundary zones. Multiple chained zones per elevation are supported.
- When loaded, these zones are used for both scroll blocking and visible area clipping (black bars), replacing both vanilla scroll blocking and CE hi-res stencil system.
- v2 EDG files also contain a `SquareRect` that defines "Angled edges", or square-grid stencil. This is also supported.
## Settings (ddraw.ini → fallout2.cfg / game.cfg)
Settings previously read from `ddraw.ini` have been moved into standard CE config files.
Most settings that control game behavior (premade characters, extra message files, combat tweaks, worldmap, etc.) have been moved into [`<DAT>/config/game.cfg`](files/ce.dat/config/game.cfg), which is a content-mod config file intended to be overridden by mods. See that file for the full list with descriptions.
The following settings were moved into [`fallout2.cfg`](files/fallout2.cfg) instead:
See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/) for documentation on specific functions.
| Group | Opcodes In Group | Compatibility | Notes |
| --- | --- | --- | --- |
| Direct memory access| read_byte,short,int,string<br>write_byte,short,int,string<br>call_offset_vX | 🚫 | Not possible. Open an issue if you need functionality not covered by other opcodes. |
| Stats | get/set_pc_base_stat<br>get/set_pc_extra_stat<br>get/set_critter_base_stat<br>get/set_critter_extra_stat | ✅ | CE uses engine stat helpers here instead of sfall's direct proto-field behavior, so derived-stat update behavior can differ. |
| Stats / Alter min/max | get/set_stat_min/max<br>set_pc_stat_min/max<br>set_npc_stat_min/max | not implemented | - |
| Skills | get/set_critter_skill_points<br>get/set_available_skill_points<br>set_skill_max<br>set_critter_skill_mod<br>set_base_skill_mod<br>mod_skill_points_per_level | not implemented | - |
| Shaders | load_shader<br>free_shader<br>activate_shader<br>deactivate_shader<br>set/get_shader_* | 🚫 | likely will not implement direct compatibility
| Perks and traits | set_perk_image<br>set_perk_*<br>set_pyromaniac_mod<br>apply_heaveho_fix<br>set_swiftlearner_mod<br>has/set_fake_perk<br>has/set_fake_trait<br>set_selectable_perk<br>set_perkbox_title<br>show/hide_real_perks<br>perk_add_mode<br>clear_selectable_perks<br>add/remove_trait<br>seq_perk_freq | not implemented | - |
| Virtual file system | fs_create<br>fs_copy<br>fs_find<br>fs_read/write_*<br>fs_delete<br>fs_size<br>fs_pos<br>fs_seek<br>fs_resize | 🚫 | Open an issue if you have a use case for these |
| Audio | play_sfall_sound<br>stop_sfall_sound | ✅ | `play_sfall_sound` currently supports `.acm`, `.wav`, `.ogg` formats, and can load from `.dat` archives. `.mp3` is not yet supported. |
| Combat / Weapons and ammo | get/set_weapon_ammo_pid<br>get/set_weapon_ammo_count | ✅ | - |
| Sfall / Version | sfall_ver_major<br>sfall_ver_minor<br>sfall_ver_build | ✅ | CE currently reports `4.3.4` |
| Utility / Math | log, exponent, round, sqrt, abs, sin, cos, tan, arctan, ceil, ^, floor2, div | ✅ | - |
| Global variables | set_sfall_global<br>get_sfall_global_int<br>get_sfall_global_float | ✅ except get_sfall_global_float | Current CE storage is int-backed; `set_sfall_global` stores integer values |
| Hooks / Hook functions | init_hook<br>get_sfall_arg<br>get_sfall_args<br>get_sfall_arg_at<br>set_sfall_return<br>set_sfall_arg<br>register_hook<br>register_hook_proc<br>register_hook_proc_spec | ✅ | See below for implemented hooks. `init_hook` is deprecated and will not be implemented. register_hook_proc and register_hook_proc_spec both add hooks to the *end* of the hook list, instead of beginning and end, respectively. |
| Interface / Main interface | intface_is_hidden<br>intface_redraw<br>intface_hide<br>intface_show<br>set_quest_failure_value | implemented: only intface_redraw | `intface_redraw` only supports the zero-argument form; the optional-argument path is explicitly unimplemented. |
| Locks | lock_is_jammed<br>unjam_lock<br>set_unjam_locks_time | not implemented | - |
| INI settings | get_ini_setting<br>get_ini_string<br>get_ini_section<br>get_ini_sections<br>get_ini_config<br>get_ini_config_db<br>set_ini_setting | ✅ | `modified_ini` is intentionally omitted as deprecated. |
| Objects and scripts | set_self<br>set_dude_obj<br>real_dude_obj<br>remove_script<br>get/set_script<br>obj_is_carrying_obj<br>loot_obj<br>dialog_obj<br>obj_under_cursor<br>get/set_object_data<br>get/set_flags<br>set_unique_id<br>set_scr_name<br>obj_is_openable<br>get/set_proto_data<br>get_object_ai_data | ✅ except set_dude_obj, set_scr_name | `get/set_object_data` maps supported object and `C_ATTACK_*` offsets instead of exposing arbitrary raw memory offsets. |
| Other / Game management | set_movie_path<br>stop/resume_game<br>mark_movie_played<br>game_loaded<br>get_game_mode<br>get_uptime<br>signal_close_game | implemented: game_loaded, get_game_mode, get_uptime, signal_close_game | - |
| Events | add_g_timer_event<br>remove_timer_event<br>create_spatial<br>spatial_radius | not implemented | - |
| Other | get_year<br>active_hand<br>toggle_active_hand<br>get/set_viewport_x/y<br>get_light_level<br>message_str_game<br>sneak_success<br>unwield_slot<br>add_extra_msg_file<br>get_metarule_table<br>metarule_exist<br> | ✅ except get/set_viewport_x/y, sneak_success | `input_funcs_available`, `nb_create_char` are deprecated in sfall and intentionally absent in CE. `add_extra_msg_file` does not support the explicit `fileNumber` form in CE. |
## Hooks
| Hook | ID | Compatibility | Notes |
| --- | --- | --- | --- |
| ToHit | `HOOK_TOHIT` | ✅ | - |
| AfterHitRoll | `HOOK_AFTERHITROLL` | ✅ | Overriding `defender` leaves a lot of attack variables in previous state (e.g. distance, ->oops, roundsHitMainTarget) |
| AmmoCost | `HOOK_AMMOCOST` | ✅ | Requires `check_weapon_ammo_cost=1` if you want pre-attack ammo validation to respect per-shot/per-round overrides. |
| KeyPress | `HOOK_KEYPRESS` | ✅ | Third hook arg is currently `0`; CE doesn't use VK codes. |
| RestTimer | `HOOK_RESTTIMER` | ✅ | CE is slightly more strict: only `ret0 == 1` interrupts. Ticks wrap every 6.8y; do not rely on them for absolute game time. |
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.