Repository navigation
Conversation
Embed per-monitor DPI awareness and maintain the verified OGRE 13.6.5 renderer patch required for context-safe window replacement, runtime GL options and correct fullscreen client geometry. Validation: clean Release build, DPI and 3440x1440 fullscreen probes, three GL3Plus variants and the patch reverse check passed; version 0.7.1 remains unchanged because this is unreleased work and the project has no changelog.
Apply display, input, audio, gameplay, minimap, shadow and negotiated nickname changes to the running session while preserving rollback for failed window or input transitions and keeping the 3440x1440 navigation visible. Validation: clean Release and Debug builds, packet tests, DPI, layout and GL3Plus probes passed; the user confirmed the reported resolution, fullscreen, cursor, flicker and navigation failures are fixed. Version 0.7.1 remains unchanged because this is unreleased work and the project has no changelog.
The spells tab put its ten buttons in a single row of 60 pixel squares running out to x=700. The pane they live in is the window width minus the 200 pixels of minimap, so at the 800 wide minimum window it is 600 pixels across, and the last two spells, Weakness and the Eye of Evil, hung past its right edge where they could be neither seen nor clicked. Only a window at least 900 wide showed the whole row, and nothing said so. The rooms tab solved the same problem long ago: two rows of 40 pixel buttons. The spells tab now uses the same shape, five spells to a row, ending at x=300 with room to spare at any size the game accepts. The cooldown bar inside each button now covers exactly its button too, instead of overhanging 20 pixels on both sides, which with narrower buttons would have bled half way across the neighbours. The rooms tab had the tail of the same bug: the temple and portal buttons the editor uses sat at x=570 to 690, past the same edge. They join the end of the second row instead. (cherry picked from commit 10db1cb)
When a human player loses the last dungeon heart, the server sends two owner-only messages appended to ServerNotificationType: playerDefeated with the conqueror seat and the heart tile, and levelStatistics with the elapsed time and six per-seat counters (keepers defeated, creatures killed, heroes destroyed, rooms captured, items made, creatures converted). The counters are kept per seat on the server and are not saved. The client stores the statistics and hands playerDefeated to a new GameMode::startDefeatSequence entry point.
On playerDefeated the client hides the interface and pointer, blocks input and cuts the camera to the destroyed heart. A client-only copy of the heart shakes and bursts into particles and a rubble pile, a swirl in the conqueror's colour leaves the heart, and a red tint, two subtitles and a fade to black follow. The timeline runs on a monotonic clock, so repeated frame callbacks do not speed it up. On the black screen a debriefing window shows the player, the outcome, the elapsed time and a per-seat statistics table from levelStatistics. Its confirm button returns to the main menu, which zooms in briefly and opens the skirmish sub-menu.
When a heart's health reaches 0, only the heart object is removed. The room keeps its floor tiles as an inert ruin with no health, so the seat has no temple any more and the existing defeat path runs as before. The ruin cannot be attacked, its floor is never released in game mode, and a saved ruin gets no new heart object on load.
The heart took its health from the durability of its floor tiles, so a 3 by 3 heart fell to a few blows. It now has 10000 health per room tile (90000 for a 3 by 3 heart); the critical warning stays at 11 % of this maximum. Only fighters damage an enemy heart: workers deal no damage to it, and a worker given a non-creature target drops its fight action. Saves write the heart health as "HeartHealth" on the new scale. An older "HeartHP" record is converted to the same share of the new maximum, a value above the maximum is limited to it, an unknown record is rejected and a destroyed heart stays a ruin.
The green ring of the heart badge now shows the remaining heart health of the local player as an arc, and the badge glows magenta for three seconds after the heart was hit. The server sends the new owner-only heartHealth notification (appended last to ServerNotificationType) when the health fraction changed by at least one percentage point, when the heart is destroyed and once when a game starts or is loaded. The client redraws the badge into its existing texture with blitFromMemory, since loadFromMemory would create a new texture that the badge never shows. The badge drawing moves into drawBadgePixels, with the symbol test as a named function instead of a lambda.
The badge icon still said "Your Mana". The heartHealth message now also carries the current and maximum heart HP, the server sends it on every whole HP change, and the client sets the icon tooltip and context line to "Dungeon Heart: current/max" every frame. The badge tooltip in the layout reads "Dungeon Heart Health" until the first message arrives.
…econd The heart maximum no longer depends on the number of covered tiles. A living damaged heart regains 2.5 / turnsPerSecond per turn up to the maximum, a destroyed heart never heals. Saves write HeartHealth10000; the older HeartHealth (per tile scale) and HeartHP records are converted by share, so a full heart stays full and a ruin stays a ruin. Messages that only carry a new whole HP are sent at most once per second; percentage point changes and destruction are still sent at once.
This was referenced Sep 27, 2026
Rokk001
force-pushed
the
pr/dungeon-heart-h1
branch
from
September 30, 2026 05:00
0dbe8cc to
7d52865
Compare
…th packets A packet that is too short only triggered a log message and left the conqueror seat, the heart tile, the seat count and the heart health values uninitialised. They now start as unknown (-1, no seats, a full heart).
Pi, the notify tolerance, the golden angle of the rubble layout and the shake, pulse and flicker frequencies get names. The arithmetic is unchanged.
…setup and initialise the defeat positions
…ns from one shared script
The Windows scripts read the dependency, Visual Studio and Python locations from one shared script, now named windows-paths.ps1 with the variables taskDependencyRoot and taskPythonCmakeRoot. The locations can still be set with OD_DEPS_ROOT, OD_PYTHON_ROOT and OD_VS_PATH.
Brings in the later changes of the defeat sequence and heart badge branch: - packet values of the defeat, statistics and heart health messages are initialised - the heart HP values of the heartHealth notification are documented - named constants for the heart health ring and the heart burst - if/else instead of nested ternaries for the badge ring colour - named functions instead of lambdas in the defeat notification check
The defeat sequence adds materials/textures/DefeatFireball.png, but the credits file had no entry for it. The texture is AI-generated for this project and released under GPLv3+, same wording as the other generated textures.
Brings in the CREDITS line for the AI-generated defeat fireball texture so this branch lists the asset it carries.
Take over the shared script locations so the Windows scripts no longer contain a personal home folder path: the dependency, Visual Studio and Python locations are read from windows-paths.ps1.
Take over the shared script locations so the Windows scripts no longer contain a personal home folder path: the dependency, Visual Studio and Python locations are read from windows-paths.ps1.
Bring the latest tip of pr/defeat-sequence-2026-09-25 into this branch so it contains everything its predecessor now has.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The heart's maximum health becomes a fixed 10000, independent of the number of covered tiles (replacing 10000 per room tile). While alive, the heart heals 2.5 per second up to the maximum; a destroyed heart never heals. Since the whole HP now changes every turn, HP-only messages are limited to one per second; percentage-point changes and destruction are still sent at once. The one-time critical warning fires again after the heart has healed above it.
Saves
The heart health is stored under a new record name for the 10000 scale; saves with the old
HeartHealth(90000 scale) orHeartHP(floor scale) records are converted by share, so a full heart stays full and a ruin stays a ruin.Stacking
This PR stacks on #197 (
pr/defeat-sequence-2026-09-25). Until it is merged, the diff against the base branch also shows its commits; the new work is the last two commits. To see only this step, compare this branch against the head of #197.Validation
check_dungeon_heart_combat.py,check_heart_health_ring.py,check_heart_ruin.py,check_level_statistics.pyandcheck_heart_badge_texture.pypass.Supersedes #148, closed and force-pushed by mistake; recreated with the same content and cleaned-up commit trailers.