feat: translate flight tutorial for next in-game trial

This commit is contained in:
DragonHD
2026-09-20 12:00:54 +08:00
parent 997ae29355
commit 6cd5bcbfee
5 changed files with 48 additions and 4 deletions
+8
View File
@@ -187,3 +187,11 @@ so centred labels (the "Start New Game" button) were flushed right. Fixed to
- Prepared matching loose atlas and in-place same-size `Textures.res` entry; bytes before and after that entry remain identical. No executable, metrics, UV table, script, or other punctuation changes. - Prepared matching loose atlas and in-place same-size `Textures.res` entry; bytes before and after that entry remain identical. No executable, metrics, UV table, script, or other punctuation changes.
- 34 tests pass. Checked original/fixed glyph bounds and exact shape preservation; rollback of both files tested against backups in an isolated directory. Comparison PNG uses actual atlas pixels enlarged 8x. - 34 tests pass. Checked original/fixed glyph bounds and exact shape preservation; rollback of both files tested against backups in an isolated directory. Comparison PNG uses actual atlas pixels enlarged 8x.
- Backup: `E:/DragonHD/backup_game/full-stop-20260920`. User explicitly authorized terminating the running game for installation. Real in-game appearance pending. - Backup: `E:/DragonHD/backup_game/full-stop-20260920`. User explicitly authorized terminating the running game for installation. Real in-game appearance pending.
## 2026-09-20 — Flight tutorial trial
- User accepted full-stop correction. Continued with flight only: title, message and mission description (literal indexes 1214). Two concise centered paragraphs retain mouse destination, altitude globe and keyboard movement instructions.
- All other text and non-display bytes preserved; the original movement threshold (>15 units along either horizontal axis within the timed loop) and next-button gating remain unchanged. Flight height/attack are next batches.
- 35 tests pass, including engine layout at widths 360/400/480; original/modified byte verification and rollback passed. Backup: `E:/DragonHD/backup_game/tutorial-flight-20260920/Tutorial.dsc`.
- Game stopped using user's prior termination authorization; deployed file reread and matched output. SHA256: `a41caad224f748222489f8d062526ae663bb04201c593f59d6af02d69a74f604`.
- In-game acceptance pending: enter Flight after Zoom, use left click or arrow keys to move some distance, then check Continue Tutorial becomes available and Flight height starts.
@@ -172,3 +172,10 @@ def validate_size(original, result):
- [x] 游戏退出后部署,重读游戏文件并通过校验。 - [x] 游戏退出后部署,重读游戏文件并通过校验。
- [ ] 用户实机验证首批中文显示和教程事件推进。 - [ ] 用户实机验证首批中文显示和教程事件推进。
- [ ] 首批确认后继续飞行及后续教程;Task 1 整体验收仍未完成。 - [ ] 首批确认后继续飞行及后续教程;Task 1 整体验收仍未完成。
### 飞行批次进度
- [x] 首批后续页面及句号位置经用户确认。
- [x] 飞行标题、提示、任务说明已汉化并部署;35 项测试及回滚验证通过。
- [ ] 飞行中文显示、移动后继续按钮、进入飞行高度步骤实机验收。
- [ ] 验收后继续飞行高度与攻击提示。
+26
View File
@@ -0,0 +1,26 @@
"""Flight tutorial text fits the existing dialog using actual engine layout."""
import json
from pathlib import Path
import unittest
from test_cjk_layout import layout
class FlightTests(unittest.TestCase):
def test_flight_instructions_fit_and_share_dialog_center(self):
mapping = json.loads(Path(__file__).with_name('tutorial_cn.json').read_text(encoding='utf-8'))
bodies = [v for k, v in mapping.items() if k.startswith('\fYou can fly')]
self.assertEqual(len(bodies), 2)
self.assertEqual(bodies[0], bodies[1])
for body in bodies:
for width in (360, 400, 480):
lines, _ = layout(body, width=width, alignment=0)
self.assertEqual(len(lines), 2)
for raw, x, y in lines:
text = raw.decode('gb2312')
self.assertEqual(x, (width - len(text) * 12) // 2)
self.assertNotIn(text[0], ',。;:、')
self.assertEqual(lines[1][2] - lines[0][2], 17)
if __name__ == '__main__':
unittest.main()
+4 -1
View File
@@ -7,5 +7,8 @@
"Center the camera": "镜头回正", "Center the camera": "镜头回正",
"\fTo bring the camera into the default position behind the dragon press on the \"5\" key on the numeric keypad.": "\f按数字小键盘上的 5 键,将镜头恢复到巨龙身后的默认视角。", "\fTo bring the camera into the default position behind the dragon press on the \"5\" key on the numeric keypad.": "\f按数字小键盘上的 5 键,将镜头恢复到巨龙身后的默认视角。",
"Zoom": "缩放视角", "Zoom": "缩放视角",
"\fYou can zoom the camera by rotating the mouse wheel or by pressing the \"+\" and \"-\" keys on the numeric keypad.": "\f滚动鼠标滚轮,或按数字小键盘上的 +、- 键,可拉近或拉远视角。" "\fYou can zoom the camera by rotating the mouse wheel or by pressing the \"+\" and \"-\" keys on the numeric keypad.": "\f滚动鼠标滚轮,或按数字小键盘上的 +、- 键,可拉近或拉远视角。",
"Flight": "飞行",
"\fYou can fly using the mouse or the keyboard. Just left-click anywhere - and your dragon will fly there (note the indicator that appears there with a light globe that marks your dragon's altitude).\n\fYou can also use the keyboard to fly: up arrow moves forward, left and right arrow keys steer.": "\u0007左键点击目的地即可飞行,光球表示飞行高度。\n\u0007也可用方向键:上键前进,左、右键转向。",
"\fYou can fly using the mouse or the keyboard. Just left-click anywhere - and your dragon will fly there (note the indicator that appears there with a light globe that marks your dragon's altitude).\n\fYou can also use the keyboard to fly: up arrow moves forward, left and right arrow keys steer.": "\u0007左键点击目的地即可飞行,光球表示飞行高度。\n\u0007也可用方向键:上键前进,左、右键转向。"
} }
+3 -3
View File
@@ -1,4 +1,4 @@
"""Verify the bounded first tutorial translation against an original backup.""" """Verify the bounded first five tutorial groups against an original backup."""
import argparse import argparse
import hashlib import hashlib
import json import json
@@ -38,8 +38,8 @@ def main():
assert source[a.start:a.end] == result[b.start:b.end] assert source[a.start:a.end] == result[b.start:b.end]
left, right = a.end, b.end left, right = a.end, b.end
assert source[left:] == result[right:], 'trailing bytes changed' assert source[left:] == result[right:], 'trailing bytes changed'
assert changed == list(range(12)), changed assert changed == list(range(15)), changed
print('MODIFIED: first 12 of 55 literals translated; all other bytes unchanged; PASS') print('MODIFIED: first 15 of 55 literals translated; all other bytes unchanged; PASS')
if __name__ == '__main__': if __name__ == '__main__':