Skip to content

Vary creature portrait colours per creature - #248

Open
Rokk001 wants to merge 81 commits into
tomluchowski:shaders-improvementfrom
Rokk001:feature/creature-portrait-tints
Open

Rokk001 wants to merge 81 commits into
tomluchowski:shaders-improvementfrom
Rokk001:feature/creature-portrait-tints

Conversation

@Rokk001

@Rokk001 Rokk001 commented Oct 1, 2026 •

Copy link
Copy Markdown

Gives each creature its own portrait colour variation (hair, beard, eyes, skin, teeth), configured in config/portrait-tints.cfg and applied in the profile card and the Dungeonbook. The variation is deterministic per creature. The population panel and hand icons are unchanged.

Stacked on #247 (feature/creature-social-feed) and through it on the profile card PR. Review this PR alone: compare of the 1 own commit.

Related: #220 (standalone portrait exporter, a different topic; this PR does not change the exporter tool) and #225 (portrait assets and the CreaturePortrait files this builds on).

Tint variants, Orc
Tint variants, Dwarf
Tint variants, Elf

These previews also use the gender images of the next PR.

Verification: Release build of this branch; check_creature_portrait_tints.py passes (34 meshes). Mario tested the integrated build in game. No gameplay, network or save game effect.

Update 2026-10: aligned with the current development state

Checked against the current development branch. Taken over from it, with only the lines each commit changes:

  • "Remove the two base tint blocks that name catalog ids without a real manifest" (base tint configuration only)

Further commits in this update: credits for the two overlay textures CreatureExperience.png and CreatureRecovery.png (AI-generated), removal of provenance wording in the portrait notes and a GUI comment, and removal of a duplicated declaration in the creature info page. A first attempt at the tint commit replaced the whole file; it was reverted and redone with only the commit's own lines (both stay in the history).

The remaining own files still differ from the development branch because of later commits that belong to other features and are not part of this PR (neutral portrait bases and measured tint regions, gender portraits, composed Dungeonbook pictures, shared portrait renderer).

Validation: release build verified on the pushed tip.

Rokk001 and others added 30 commits September 7, 2026 00:45
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)
Remove depleted fills and borders while preserving surviving health segments and the centre. Update player guidance and add the 200-check texture regression. No release version or protocol change is needed; the existing PR documents this unreleased feature correction.
# Conflicts:
#	source/entities/Creature.cpp
Replace the hardcoded dependency, Python and Visual Studio locations in the
Windows scripts with a shared windows-paths.ps1. The defaults derive from the
current user profile and can be overridden with OD_DEPS_ROOT, OD_PYTHON_ROOT
and OD_VS_PATH.
Replace the auto declarations introduced by this branch with explicit types,
as requested in issue tomluchowski#42 and required by CLAUDE.md. No behavioural change.
Replace the auto declarations introduced by this branch with explicit types,
as requested in issue tomluchowski#42 and required by CLAUDE.md. No behavioural change.
Replace the auto declarations introduced by this branch with explicit types,
as requested in issue tomluchowski#42 and required by the project coding guidelines. No behavioural change.
The middle button rotates the camera and, on press, also opened the stats
window of the creature under the pointer. Rotating over creatures therefore
opened windows the player never asked for. The window now opens when the
button is released without the pointer having moved more than a few pixels;
a middle drag only rotates.

Also explain the KO checkbox in the player settings with a tooltip.
The creature and tile info windows were built in code with a fixed
380 x 400 pixel size that was never scaled while the fonts were, so the
text was huge and cut off. They are now loaded from the new
gui/WindowStats.layout through Gui::createInfoWindow() and registered
for UI scaling like every other layout: fixed 540 x 490 layout units,
centred, not resizable (moving and closing stay), text top aligned and
word wrapped, body text in MedievalSharp-8 and headings in
MedievalSharp-10. A creature lists its next four destinations and the
total count, so the text fits the fixed window.

Check: source/tests/check_info_window.py (no sizing, fixed size, body
font, formatting, both entities use the layout).

Depends on the GUI scaling (tomluchowski#209) for Gui::registerWindowHierarchy().
…e it

Add compose on raw RGBA buffers with alpha blending in slot order and helmet
damage limited to the helmet alpha for Knight and Cultist, the shared tint
path with a separate base tint config, a client side picture cache with LRU
and size limits, and the fallback signal for missing manifests.
…nbook

Fill the profile page and the creature card from the composed appearance
picture and fall back to the tinted preview portrait only when there is none.
Add profile remarks that match the parts (config/dungeonbook-quirks.cfg),
chosen with a fixed hash from name and appearance, a separation check for
the creature bar, tests for remarks and for two clients plus a late joiner,
and the outfit slot in the manifest loader. Existing notification order
checks now ignore the appended appearance notification.
…ication order checks skip the appended appearance entry
…er creature

The neutral bases have no hair, eyes or beards, so their colours are applied to the chosen parts
before composing (part tint file, same PortraitTint code path and name based colour choice).
Hair and beard parts share one colour; eye irises are tinted through measured ellipse regions
for the options that could be separated cleanly. The skin amplitude of the bases comes from a
base-skin entry, so bases delivered without an amplitude still vary per creature.

Quirk remarks now use the real option names of the manifests, are placed after status and
latest post so the card layout of those stays put, and the card gets room for them.
New static checks cover the tint files, the profile layout and the test registration.
The profile page (creature card and Dungeonbook share it) now has a scrollbar at its right edge that
appears only when the rows are higher than the page, and all rows move with it. The card is taller
so the usual content with remarks fits without scrolling. The layout check models the heights for
several resolutions and user scales, typical and worst case.
… wheel scrolling, golden test

- First spawn rolls until the look is free; a duplicate is only accepted when every combination of the
  catalog id is already in use (64 bit saturating count, no fixed number of tries).
- The manifest registry gives failed manifests another chance on request: the server retries before it
  derives a late look, the client every few seconds; a failure that stays the same is logged once.
- Composing is plain source-over in manifest order; the scar and helmet masks are baked into the part
  images, so the runtime clipping of scars to the helmet is gone.
- The mouse wheel scrolls the profile page (card and Dungeonbook) while its scrollbar is shown; in the
  Dungeonbook the profile leaves a fixed room for the recent posts and scrolls inside.
- Golden test of composing plus tinting with an exactly derivable scene and a script that recomputes it.
Orc and Troll eyes use fire, Kobold eyes use glow (with the colour limits of the old regions), and
Monk (female) hair uses hair_brown, with the same palette colours in the same order and the same
region names as portrait-tints.cfg, so a creature gets the same palette colour as in the old
portrait. A block for a catalog id now replaces the generic block of that part. The tint check
compares the palettes with the old file and the catalog ids with the old regions.
…he iris

- A creature whose stored look was never checked against a manifest (loaded or spawned without one) is
  checked on the retry loop as soon as the manifest is valid; removed options are replaced stably from
  the name and the clients are told when the look changed. The client display replaces removed options
  the same way.
- Eye tint regions were audited against the artwork: the Kobold eye patch option is left untinted, the
  Kobold round option and the Orc options got tighter limits, and a new check enforces a limit for tinted
  pixels outside the iris area.
…heck

A creature without a catalog id remembers that and is not looked at again until the registry's catalog
generation changes. The registry remembers which catalog folders exist and forgets that once per retry
period for all creatures together, so a folder that appears later is still found without a file lookup
per creature and upkeep.
…, add the brown hair palette and name the meshes as the creature definitions do

Without the header the first palette was not read, and the mesh names without the model suffix never matched a creature, so no portrait was tinted. The Dungeonbook part tints refer to the brown hair palette.
… which only exists where held creatures are shown at the pointer
The editor region, level script and sandbox score checks test code that this change does not contain, so they move to the changes that add that code.
The records and the neutral base notes named the folder of the local image
generator. They now only name the generated file, so no personal path is
stored in the repository. The images are unchanged.
The two overlay textures CreatureExperience.png and CreatureRecovery.png are part of this branch but had no CREDITS entry. Add one with source, licence and the AI-generated mark.
The remarks block (declaration of quirks, its filling and the two text updates) was present twice in a row, which stopped the file from compiling because quirks was declared twice. One copy is kept, as in the main line.

This branch has not been deployed

No deployments
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