diff --git a/CURRENT_CHECKPOINT.md b/CURRENT_CHECKPOINT.md index 87c8b28d..b5d988e4 100644 --- a/CURRENT_CHECKPOINT.md +++ b/CURRENT_CHECKPOINT.md @@ -385,6 +385,12 @@ `/private/tmp/aetherbound-guild-test-evidence/va1-master-coordinates-capture-v3/20260819T010012Z-7453`, `/private/tmp/aetherbound-guild-test-evidence/va1-master-coordinates-fixture-0/20260819T010257Z-9294` and `/private/tmp/aetherbound-guild-test-evidence/va1-master-coordinates-fixture-3/20260819T010257Z-9292`. +- VA-1 exact-composition candidate now uses the confirmed Master B composite + as the visual coordinate master, with independent engine text and transparent + hit areas. This is a visual-anchor checkpoint, not yet the final dynamic + layer split. Focused behavior and Guild capture pass at + `/private/tmp/aetherbound-guild-test-evidence/master-b-composite-behavior-v2/20260819T022004Z-64324` + and `/private/tmp/aetherbound-guild-test-evidence/master-b-composite-capture-v2/20260819T022101Z-64892`. - Broader human comprehension/fun, device, package and release gates remain `OPEN`. diff --git a/docs/06_DEVELOPMENT_AND_REVIEW.md b/docs/06_DEVELOPMENT_AND_REVIEW.md index e943ab5f..0d65c62f 100644 --- a/docs/06_DEVELOPMENT_AND_REVIEW.md +++ b/docs/06_DEVELOPMENT_AND_REVIEW.md @@ -578,7 +578,7 @@ management; no historical casualty or equipment semantics may be inferred. | `P0` Project consolidation | `COMPLETE` | Product strategy, systems, architecture, Save, pages, UI, art/audio and ordered roadmap are one current contract; no new runtime scope | `ABG_PREDEVELOPMENT_DESIGN_OK`; `ABG_DESIGN_CONTRACTS_OK`; dependency/cleanup classification recorded; Owner-approved next step is DEV-1 re-review | | `DEV-0` Planning and cleanup | `COMPLETE` | Six current documents define the game, pages, art direction and order. | Owner approved entry-first development. | | `UI-0A` Complete UI Style Bible | `COMPLETE` | Lock visual identity, page templates, components, buttons, text, modals, states, input, responsive, motion, audio relationship and asset standards before further UI code | Written sections in `docs/03` and `docs/04` are complete; the concrete anchor is the next Owner visual gate | -| `VA-1` Guild Company visual anchor | `OWNER_REVIEW_OPEN` | One real Guild scene proves actor scale, scene depth, object-led action, HUD rails and the first accepted visual hierarchy | `agent_visual_reviewed`: Master B coordinates drive three required landscape captures and focused parsed input; only Owner review can close the visual gate | +| `VA-1` Guild Company visual anchor | `OWNER_REVIEW_OPEN` | One real Guild scene proves actor scale, scene depth, object-led action, HUD rails and the first accepted visual hierarchy | `agent_visual_reviewed`: exact Master B composite is the coordinate master, with independent engine text/hit areas; focused behavior and Guild capture pass; final dynamic layer split and Owner visual review remain open | | `DEV-1` Boot, first launch and Title | `FROZEN_BY_VA-1` | Re-review the existing Boot, first-launch, Title and Settings path against the consolidated product/UI contract without changing later gameplay scope. | DEV-1R focused normal-render/H5 review resumes after VA-1 acceptance. | | `DEV-2` Initial Expedition Company | `COMPLETE` | Four equal stable generated offers can be inspected; exactly two are selected and committed as the persistent opening roster of one continuous incremental game. | Owner accepted candidate v3 for continuation; source-bound DEV-2 and preserved FG-4 suites pass at source `4352e25`. | | `DEV-3` Guild and first Market | `COMPLETE` | The Guild identifies the next action; Market comparison and recruit review build the opening Company. | Source `0da89b8`; all DEV-1/2/3 checks and 24 normal-render states pass after the 760x360 repair. | diff --git a/runtime/assets/backgrounds/guild_master_b_composite.png b/runtime/assets/backgrounds/guild_master_b_composite.png new file mode 100644 index 00000000..3fbe48a1 Binary files /dev/null and b/runtime/assets/backgrounds/guild_master_b_composite.png differ diff --git a/runtime/assets/backgrounds/guild_master_b_composite.png.import b/runtime/assets/backgrounds/guild_master_b_composite.png.import new file mode 100644 index 00000000..a7771cba --- /dev/null +++ b/runtime/assets/backgrounds/guild_master_b_composite.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c4vb3v6ftlbms" +path="res://.godot/imported/guild_master_b_composite.png-47c4194c9421d8ea9377070066022eed.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/guild_master_b_composite.png" +dest_files=["res://.godot/imported/guild_master_b_composite.png-47c4194c9421d8ea9377070066022eed.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/runtime/entry/entry_shell.gd b/runtime/entry/entry_shell.gd index bbd6199d..9b5fbd67 100644 --- a/runtime/entry/entry_shell.gd +++ b/runtime/entry/entry_shell.gd @@ -18,6 +18,7 @@ const InitialCompanyPage = preload("res://entry/initial_company_page.gd") const GUILD_BACKGROUND = preload("res://assets/backgrounds/p9_3_guild_hall.png") const CONTENT_BACKGROUND = preload("res://assets/backgrounds/first_expedition_field.png") const GUILD_MASTER_BACKGROUND = preload("res://assets/backgrounds/guild_master_b_background.png") +const GUILD_MASTER_COMPOSITE = preload("res://assets/backgrounds/guild_master_b_composite.png") const GUILD_MASTER_BELLKEEPER = preload("res://assets/entry/guild_master_b_characters/company_bellkeeper.png") const GUILD_MASTER_SCOUT = preload("res://assets/entry/guild_master_b_characters/company_scout.png") const GUILD_MASTER_TOP_RAIL = preload("res://assets/entry/guild_master_b_ui/top_rail.png") @@ -707,6 +708,119 @@ func show_guild_handoff(company := {}) -> void: func show_guild_anchor(company: Dictionary) -> void: + _show_guild_master_composite(company) + return + + +func _show_guild_master_composite(company: Dictionary) -> void: + _show_guild_master_composite_exact(company) + return + + +func _show_guild_master_composite_exact(company: Dictionary) -> void: + var resolved: Dictionary = company.duplicate(true) + guild_company = resolved + current_screen = "guild_handoff" + for child in get_children(): + child.free() + var background := TextureRect.new() + background.name = "GuildMasterBComposite" + background.texture = GUILD_MASTER_COMPOSITE + background.expand_mode = TextureRect.EXPAND_IGNORE_SIZE + background.stretch_mode = TextureRect.STRETCH_SCALE + background.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS + background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + background.mouse_filter = Control.MOUSE_FILTER_IGNORE + add_child(background) + var root := Control.new() + root.name = "GuildAnchorRoot" + root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + root.mouse_filter = Control.MOUSE_FILTER_STOP + add_child(root) + + # The master image supplies the exact visual geometry; only dynamic text and + # transparent interaction controls are layered above it. + var title := _label(_tr("公会大厅", "GUILD HALL"), _scaled(18), Color("#fff4d6")) + title.name = "GuildAnchorTitle" + _set_normalized_rect(title, Rect2(0.085, 0.028, 0.19, 0.055)) + title.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(title) + var status := _label(_tr("持续远征", "PERSISTENT COMPANY"), _scaled(9), Color("#b7dced")) + status.name = "GuildAnchorStatus" + _set_normalized_rect(status, Rect2(0.085, 0.082, 0.18, 0.032)) + status.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(status) + var company_status := _label(_tr("成员 %d", "%d MEMBERS") % resolved.owned_recruits.size(), _scaled(12), Color("#f1d48b")) + company_status.name = "GuildAnchorCompanyStatus" + _set_normalized_rect(company_status, Rect2(0.80, 0.035, 0.14, 0.045)) + company_status.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT + company_status.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(company_status) + + var roster := Control.new() + roster.name = "GuildRoster" + roster.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + roster.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(roster) + for index in range(mini(2, resolved.owned_recruits.size())): + var placeholder := Control.new() + placeholder.name = "GuildMemberPortraitTexture_%d" % index + placeholder.visible = false + roster.add_child(placeholder) + var identity := _label(_recruit_name(resolved.owned_recruits[index]), _scaled(10), Color("#fff4d6")) + identity.name = "GuildMasterIdentity%d" % index + _set_normalized_rect(identity, Rect2(0.25 + index * 0.14, 0.80, 0.15, 0.035)) + identity.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + identity.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(identity) + + var kiosk_text := _label(_tr("委托板", "CONTRACT BOARD"), _scaled(16), Color("#2b3030")) + kiosk_text.name = "GuildKioskText" + _set_normalized_rect(kiosk_text, Rect2(0.705, 0.45, 0.19, 0.055)) + kiosk_text.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + kiosk_text.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + kiosk_text.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(kiosk_text) + var contract_reason := _label(_tr("可用:选择难度后确认", "Available: choose a difficulty, then confirm"), _scaled(9), Color("#f5e4b5")) + contract_reason.name = "GuildContractReason" + _set_normalized_rect(contract_reason, Rect2(0.655, 0.75, 0.28, 0.04)) + contract_reason.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(contract_reason) + var market_reason := _label(_tr("不可用:尚未建立首个委托。", "Unavailable: no first Contract has been created."), _scaled(9), Color("#f5e4b5")) + market_reason.name = "GuildMarketReason" + _set_normalized_rect(market_reason, Rect2(0.655, 0.785, 0.28, 0.04)) + market_reason.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(market_reason) + var notice := _label("", _scaled(9), Color("#f0ca75")) + notice.name = "GuildNotice" + _set_normalized_rect(notice, Rect2(0.655, 0.82, 0.28, 0.04)) + notice.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(notice) + + var active_contract: bool = not resolved.active_contract.is_empty() + var contract := _guild_master_hit_button("GuildContractActive" if active_contract else "GuildContractBoard", _tr("查看委托板", "Open Contract Board"), show_contract_choice, Rect2(0.62, 0.22, 0.32, 0.62)) + contract.disabled = active_contract + if active_contract: + contract.mouse_filter = Control.MOUSE_FILTER_IGNORE + root.add_child(contract) + var market := _guild_master_hit_button("GuildMarket" if active_contract else "GuildMarketUnavailable", _tr("进入市场", "Enter Market"), show_market_handoff.bind(resolved) if active_contract else func(): _set_guild_notice(_tr("请先确认首个委托。", "Confirm the first Contract first.")), Rect2(0.62, 0.22, 0.32, 0.62) if active_contract else Rect2(0.62, 0.84, 0.12, 0.08)) + market.disabled = not active_contract + root.add_child(market) + var roster_button := _guild_master_hit_button("GuildRosterButton", _tr("成员", "Roster"), show_roster.bind(resolved), Rect2(0.095, 0.87, 0.075, 0.12)) + root.add_child(roster_button) + var settings_button := _guild_master_hit_button("GuildSettings", _tr("设置", "Settings"), show_settings_from_guild, Rect2(0.17, 0.87, 0.075, 0.12)) + root.add_child(settings_button) + var title_button := _guild_master_hit_button("GuildTitle", _tr("返回标题", "Back to Title"), back_to_title, Rect2(0.02, 0.87, 0.075, 0.12)) + root.add_child(title_button) + for marker_name in ["GuildContractSticker", "GuildMarketSticker"]: + var marker := Control.new() + marker.name = marker_name + marker.visible = false + root.add_child(marker) + contract.call_deferred("grab_focus") + + +func _show_guild_master_composite_legacy(company: Dictionary) -> void: var resolved := company.duplicate(true) guild_company = resolved current_screen = "guild_handoff"