Compare commits

...

10 Commits

Author SHA1 Message Date
sneedmaster
4e04ec8cde DS_Store 2025-12-21 16:41:46 +01:00
sneedmaster
cccc928b2d Patch pro Onikakushi, vývojové prostředí 2025-12-21 16:40:07 +01:00
drojf
793eac7ac2 Add missing entries to text-edits.json
- Merged from French translation using the scripts/Manually Run Scripts/MergeMultipleTextEdits.py script
2025-12-13 11:28:53 +11:00
drojf
aa4f85965a Add "english mode" option for text edit merging script
- This mode forces the "NewEnglish/NewJapanese" to match the "CurrentEnglish/CurrentJapanese"
2025-12-13 11:27:52 +11:00
drojf
3f6234be4f [text-edits] Indicate where 'Back' button appears in game 2025-08-25 17:36:23 +10:00
drojf
9fc18ac183 Fix local 7za/7z (from download) not being found by main.rs
- Gave "Warning: '7za' not found - trying '7z' instead" error and then panic
2025-04-01 21:45:27 +11:00
drojf
2684c93040 Update text-edits.json for Hou+ Music Room Buttons 2025-04-01 21:12:34 +11:00
drojf
799154c867 [Hou+] Add special 'EXIT' Back button to text-edits.json
- Hou+ Special 'EXIT' Back button - this back button is shown during the 'Scenario Unlock' menu, and for some reason says 'EXIT' (in English) when the language is set to Japanese
2024-08-14 20:25:55 +10:00
drojf
b16ce1ea0b Add missing Hou+ images for translators
- TitleHigurashi is the buttons on the title menu (similar to previous chapters)
 - ChapterPreview contains the "EXIT" button on the scenario select/fragment menu, along with some other graphical (non-text) stuff
2024-08-14 20:14:56 +10:00
drojf
12cbbb574c Fix compile errors on latest rust 2024-08-14 20:11:59 +10:00
34 changed files with 1388 additions and 431 deletions

View File

@@ -1,37 +0,0 @@
name: Build ui-compiler.exe and optionally Build Assets
on:
push:
tags:
- '*'
jobs:
windows_build:
name: Windows Build
runs-on: windows-latest
steps:
# Download the repository
- uses: actions/checkout@v2
# Caching for Rust
- name: Cache rust builds
uses: Swatinem/rust-cache@v2
- name: Build ui-compiler.exe
run: cargo build
- name: Download and install dependencies, then build assets
run: python build.py github_actions
# Publish a release (tagged commits)
# For more info on options see: https://github.com/softprops/action-gh-release
- name: Release (tag)
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/') # only publish tagged commits
with:
files: |
output/*.7z
target/debug/ui-compiler.exe
draft: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3
.gitignore vendored
View File

@@ -1,7 +1,10 @@
# Protože osobně používám venv...
/venv
/assets/vanilla /assets/vanilla
/output /output
/target /target
**/*.rs.bk **/*.rs.bk
**/.DS_Sotre
/64bit /64bit
lastModified.json lastModified.json
7za.dll 7za.dll

175
Cargo.lock generated
View File

@@ -14,9 +14,9 @@ dependencies = [
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.19" version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -32,33 +32,33 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.10" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.20" version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "num-conv" name = "num-conv"
@@ -83,27 +83,39 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.78" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.35" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.6.0" version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -112,24 +124,24 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.27" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.197" version = "1.0.207"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.197" version = "1.0.207"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -138,9 +150,9 @@ dependencies = [
[[package]] [[package]]
name = "simplelog" name = "simplelog"
version = "0.12.1" version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369" checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0"
dependencies = [ dependencies = [
"log", "log",
"termcolor", "termcolor",
@@ -149,9 +161,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.51" version = "2.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -160,18 +172,18 @@ dependencies = [
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.1.3" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.34" version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa", "itoa",
@@ -192,9 +204,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]] [[package]]
name = "time-macros" name = "time-macros"
version = "0.2.17" version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [ dependencies = [
"num-conv", "num-conv",
"time-core", "time-core",
@@ -215,33 +227,84 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.6" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"winapi", "windows-sys",
] ]
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "windows-sys"
version = "0.4.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

View File

@@ -6,5 +6,5 @@ edition = "2021"
[dependencies] [dependencies]
Inflector = "*" Inflector = "*"
log = "0.4.20" log = "0.4"
simplelog = "0.12.1" simplelog = "0.12"

263
README.md
View File

@@ -1,262 +1,5 @@
# UI Compiler # Překlad uživatelského rozhraní do češtiny
Scripts for easier editing of Unity assets for Higurashi. Tento repozitář bude obsahovat přeložené Unity assety pro Higurashi a skripty na kompilaci. Byl také sobecky přizpůsoben unixovým systémům. S mírnými úpravami by měl fungovat i na Oknech™.
The main rust script will generate a new emip file, apply it to the assets and pack the assets into 7zip archive we need for a release. Pro více informací a zasloužené titulky autorů, bez kterých by tento projekt nebyl uskutečnitelný, se prosím podívejte na [původní repozitář](https://github.com/07th-mod/ui-editing-scripts).
## Documentation Notes
Please note that documentation is in two places:
1. This Readme.md file (for basic usage information)
2. [Detailed documentation with images etc. on our Wiki](https://07th-mod.com/wiki/developer/sharedassets/ui-editing-scripts/).
- You don't need to read all of this to use the tool!
----
## Instructions for Translators
Overall, the workflow for translators is:
1. Setup your computer to run our tool, including cloning or forking this repo
2. Modify/replace the files in the repo with your translated versions
3. Run our tool to generate the `.assets` and `.languageSpecificAssets` files you can include in your release
Please continue with detailed instructions below.
### Setup (Windows Only)
The below instructions only work on Windows!
1. Follow [the instructions here](https://phoenixnap.com/kb/how-to-install-python-3-windows) to install Python 3, and make sure Python is on your path
- If the above link doesn't work, just make sure you do the following:
- During the install, make sure you tick the checkbox "Add Python 3 to PATH"
- After the install is finished, **open a fresh command window**, then type `python` to check if python is correctly on your path (should display the python prompt)
2. For translators, fork this repository ([Github forking instructions]( https://docs.github.com/en/get-started/quickstart/fork-a-repo))
- A fork is recommended for translators as you can check in your changes to github. It also allows you to use Github for building and hosting assets
3. Clone the repository (either this repository, or the one you forked) to your computer
### Modifying images, text, and fonts
#### To modify images
To modify images, replace the image files in the `assets/images` folder.
Folder info:
- `images/shared`: images common to all chapters
- `images/question_arcs`: images specific to chapters 1-4
- `images/answer_arcs`: images specific to chapters 5-8
- `images/specific/[CHAPTER_NAME]`: images specific to a particular chapter
- `images/version-specific/[CHAPTER_NAME]`: images specific to a particular chapter + unity version combo
Make sure have a quick look at all the folders before starting work, so you don't miss any images by accident.
#### To modify text
The game contains various text which is not contained in the game script or the DLL (it is stored directly in the .assets file). This text is also not stored as image files, so you can't edit an image to change it.
To edit these text files, edit the `assets/text-edits.json` file. **Please read <https://07th-mod.com/wiki/developer/sharedassets/ui-editing-scripts/#unitytextmodifier> for more details on how to edit this file.**
#### To modify fonts
To modify fonts, see
- For Chapters 1-8: <https://07th-mod.com/wiki/developer/sharedassets/ui-editing-scripts/#adding-font-support-for-a-new-language-chapters-1-8-only>
- Note: Due to some Unity plugins being no longer supported, you may have trouble following these instructions. Please let us know if you have problems and we'll try to sort it out.
- For Chapter 9 <https://07th-mod.com/wiki/developer/sharedassets/ui-editing-scripts/#adding-font-support-for-a-new-language-higurashi-rei-onwards-only>
Fonts are stored in the `assets/fonts` folder as `*.dat` files, with the exception of Rei where fonts are stored in the `assets/files-2019.4` folder.
#### To modify other files
The `assets/files-[UNITY_VERSION]` folders contain files applied to a particular Unity version, regardless of chapter. You normally don't need to modify these files.
Currently these folders contain higher quality caret sprites (the little cursor/triangle displayed at the end of a text line), with the exception of the `assets/files-2019.4` folder which also contains fonts for Higurashi Rei.
### Avoiding installing python packages globally (optional)
The `build.py` script will automatically install the packages in `requirements.txt` globally.
If you do not wish to install globally, create virtual environment before running the program:
```
# Create a new virtual environment in the `venv` folder
python -m venv venv
# Activate the venv in cmd.exe
venv\Scripts\activate.bat
# OR Activate the venv in PowerShell
venv\Scripts\Activate.ps1
# Now your shell should be prefixed with `(venv)`
# Run the script
python build.py onikaushi
```
Make sure to activate the venv every time you want to run the script.
### Generating .assets and .languageSpecificAssets files (Windows Only)
To list the supported Higurashi chapters for this tool, run
```python build.py```
which should show an error message and list available chapters
Then run
```python build.py onikakushi```
Then the output files will be located in the `output/translation` folder. You can then merge the `HigurashiEp0X_Data` folder with the one in your release. **Please include all the files (not just the `sharedassets0.assets` file), so the installer can select the correct file at install time.**
If you want to rebuild all chapters, run `python build.py all` to build all chapters.
### Common Problems
You may encounter the following problems:
- Windows Defender may block/delete our precompiled `ui-compiler.exe`. In this case, you can either try to unblock it, or install Rust to make the script compile it on your own computer. Contact us if you have this issue.
- For any other error, likely we just need to update the build script, so please contact us.
### Updating dependencies
**NOTE: The script should automatically detect if the vanilla assets or UABE has changed, and re-download them. But if that doesn't work, use the '--force-download' option like so:**
```python build.py rei --force-download```
## Instructions for Dev Team
Instructions are the same as for translators, but archive files will be automatically created in the `output` folder
----
## Modifying Assets
Assets are located in the `assets` folder. Replace any file in the `assets` folder, then run the script again, and it should be included in the generated assets files.
### Building assets using Github Actions
#### Note for forks/translators
Github actions might be disabled for your forks. Clicking on the 'Actions' tab should allow you to enable it. Please do this before proceeding.
----
## Triggering Github Actions Builds
### Building a release
To use Github Actions to build a release, create a tag like `v1.0.6_onikakushi` which contains the chapter name (separated by an underscore) you want to build (or 'all' for all chapters).
Click on the 'Actions' tab to observe the build process.
Once the build is complete, go to the 'Releases' page, and a new draft release should appear. You can check everything is OK before publishing the release, or just download the files without publishing the release.
Note that doing this will build both the `translation.7z` file for translators to use, and also the individual archives for the 07th-mod developers to use.
### Building `ui-compiler.exe` using Github Actions
To build just the `ui-compiler.exe` using Github Actions (on Github's server), push any tag to the repository.
----
## New Episode Preperation Instructions
The following information is only used when adding support for a new episode.
Please look through the detailed documentation, especially if you're working on a new chapter, new language, or using UABE - this file does not contain information on those topics.
### WARNING about Unix/MacOS `sharedassets0.assets`
We've found that the MacOS sharedassets can be used on Linux, **but the Linux sharedassets CANNOT be used on MacOS in certain cases**, giving you the "purple text" issue.
For this reason, whenever a new chapter is prepared, the 'vanilla' unix `sharedassets0.assets` should be taken from the MacOS version.
### Initial dumping of textures
You will initially want to inspect all the textures in the UI file to see if any new images need to be added to the `assets/images/*` folders.
1. Open and select the `sharedassets0.assets` **AND** the `sharedassets0.assets.resS` from the new episode in UABE
2. Click the "Type" column to sort by "Type"
3. Scroll down until you see "Texture2D"
4. Hold shift, then click the first "Texture2D" item
5. Continue holding shift, then click the last "Texture2D" item. This should highlight all the "Texture2D" items.
6. On the right hand side, click "Plugins"->"Export to .png"
The textures will be dumped as images in the selected folder. However please note:
1. You will need to rename them by keeping the first part of the name only - for example `ChapterPreview-sharedassets0.assets-27.png` becomes `ChapterPreview.png`
2. It is also possible to use the number (Path ID), but usually you won't do this. In the above example, rename as `27_ChapterPreview.png` (the part after the number is not used, only to describe the file for humans)
3. Make sure you put them in the right subfolder in `assets/images`, refer to "To modify images" section for details
### Preparing font files
You'll need to extract the 'msgothic' font files from the stock `.assets` file before starting:
1. Open one of the `sharedassets0.assets` from the new episode in UABE
2. Find two font files (search for `*msgothic*` and hit F3 a couple times). Note there are other files with msgothic in the name, you're looking for ~100kb files with the exact names below:
- `MonoBehaviour msgothic_0 SDF`
- `MonoBehaviour msgothic_2 SDF`
1. Click "Export Raw" and save the files to disk
2. Rename them as `msgothic_0.dat` and `msgothic_2.dat`
3. Move them to `assets/vanilla/<chapter>/msgothic_0.dat` & `assets/vanilla/<chapter>/msgothic_2.dat`
### Fixing Caret (Ch.9 onwards)
It appears the caret Sprite files need to be modified slightly, but otherwise can be copied between chapters. The caret textures (.png files) don't need to be modified.
To do this:
- Extract the caret Sprite files as .txt from Ch.9. There are 3 for each type of caret (clickwait, and pagewait carets)
- Compare the two files in Winmerge or similar
- Copy the `0 SInt64 m_PathID` value from the vanilla caret Sprite file to the mod caret Sprite file. This ensures the correct texture is referenced.
- Now we need to convert the .txt back to .dat. To do this, open the modded sharedassets, then click "Import Dump" and import the fixed caret files, overwriting the appropriate sprites. Then click "Export as Raw" to get the .dat files usable
- Place the caret files in the `assets/files-[game_name]` folder.
- Note that each time a new game is released, you will need to update the Rust script to handle the new game, and reference the `assets/files-[game_name]` folder so it knows where to copy caret/fonts from.
----
## Extra Notes
If you want to use this tool to compile assets for a different language, you can change the files in the assets directory to your needs.
## Developer Notes
Documentation for the underlying python scripts can be found [here](https://github.com/07th-mod/higurashi-dev-guides/wiki/UI-editing-scripts).
----
## Manual Setup and Running Instructions (Windows Only)
We suggest using the above `python` script intead to setup everything, but these instructions remain here for reference.
These instructions do not rely on the `build.py` script, and are roughly how we ran the `ui-editing-scripts` before the `build.py` was created.
Note: these are rough instructions only, and may need updating.
1. Install Python 3
2. Run `python -m pip install -r requirements.txt` (or `python3` instead of `python`), to install the python dependencies
3. Download [the vanilla assets from our website](http://07th-mod.com/archive/vanilla.7z), then extract them to the root of the repository (the `assets` folder in the archive will merge with the `assets` file in the repository)
4. Download and extract UABE somewhere, then make sure `AssetBundleExtractor.exe` is on your path
5. Decide whether you want to get the pre-compiled executable, or compile the executable yourself (see below):
### Option 1: Getting the pre-compiled executable
1. Download the [pre-compiled `ui-compiler.exe`](https://github.com/07th-mod/ui-editing-scripts/releases/latest/download/ui-compiler.exe)
2. Make sure it is on your path, or in the root of the repository
### Option 2: Compiling the exe yourself
1. [Follow this guide to install Rust on Windows](https://docs.microsoft.com/en-us/windows/dev-environment/rust/setup) There are some gotchas for Windows (like you need to install Visual Studio before installing rust).
2. In the root of the repository, run `cargo build` to check everything works correctly.
## Running ui-editor-scripts
- To compile a particular chapter/variant, open `build.py` and look at the valid chapters, for example:
- `onikakushi 5.2.2f1`
- `matsuribayashi 2017.2.5 unix 51100D6D`
- Run `cargo run` (compile yourself) or `ui-compiler` (pre-compiled) with the command you chose earlier. Following the previous example:
- `cargo run onikakushi 5.2.2f1`
- `cargo run matsuribayashi 2017.2.5 unix 51100D6D`
If you compiled the exe yourself, you can run the `./compileall.sh` under windows by using `git bash` which comes with Git for Windows.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 KiB

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

File diff suppressed because it is too large Load Diff

View File

@@ -258,22 +258,24 @@ def check_7z():
print(">>>> ERROR: Can't find 7zip as '7z' or '7za', even after downloading it!") print(">>>> ERROR: Can't find 7zip as '7z' or '7za', even after downloading it!")
print("Try running this script again. If it still fails, report this issue to 07th-mod") print("Try running this script again. If it still fails, report this issue to 07th-mod")
# Check that 7zip is 64-bit ### Nobody uses 32-bit systems in {CURRENT_YEAR}.
seven_zip_bitness = None ### Also this breaks on ARM
seven_zip_info = subprocess.check_output(Globals.SEVEN_ZIP_EXECUTABLE, text=True)
for line in seven_zip_info.splitlines():
if line.strip().startswith('7-Zip'):
if 'x64' in line:
seven_zip_bitness = 64
elif 'x86' in line:
seven_zip_bitness = 32
break
if seven_zip_bitness == 64: # Check that 7zip is 64-bit
print("7zip is 64-bit - OK") # seven_zip_bitness = None
else: # seven_zip_info = subprocess.check_output(Globals.SEVEN_ZIP_EXECUTABLE, text=True)
print(f">>>> ERROR: Unacceptable 7zip bitness '{seven_zip_bitness}' - need 64 bit.\n\n Please make sure your 7zip is 64-bit, or manually edit this script to use 128mb 7z dictionary size") # for line in seven_zip_info.splitlines():
exit(-1) # if line.strip().startswith('7-Zip'):
# if 'x64' in line:
# seven_zip_bitness = 64
# elif 'x86' in line:
# seven_zip_bitness = 32
# break
# if seven_zip_bitness == 64:
# print("7zip is 64-bit - OK")
# else:
# print(f">>>> ERROR: Unacceptable 7zip bitness '{seven_zip_bitness}' - need 64 bit.\n\n Please make sure your 7zip is 64-bit, or manually edit this script to use 128mb 7z dictionary size")
# exit(-1)
class LastModifiedManager: class LastModifiedManager:
savePath = 'lastModified.json' savePath = 'lastModified.json'

View File

@@ -14,12 +14,21 @@ import json
class Fragment: class Fragment:
order = 0 order = 0
def __init__(self, fragment_as_dictionary: dict[str, str]): def __init__(self, fragment_as_dictionary: dict[str, str], en_mode: bool):
self.current_english = fragment_as_dictionary['CurrentEnglish'] self.current_english = fragment_as_dictionary['CurrentEnglish']
self.current_japanese = fragment_as_dictionary['CurrentJapanese'] self.current_japanese = fragment_as_dictionary['CurrentJapanese']
# When producing the "English" example .json, the 'new' fields should match the 'current' fields
# as no modification of the text is being performed.
if en_mode:
self.new_english = self.current_english
self.new_japanese = self.current_japanese
else:
self.new_english = fragment_as_dictionary['NewEnglish'] self.new_english = fragment_as_dictionary['NewEnglish']
self.new_japanese = fragment_as_dictionary['NewJapanese'] self.new_japanese = fragment_as_dictionary['NewJapanese']
self.discriminator = fragment_as_dictionary.get('Discriminator') self.discriminator = fragment_as_dictionary.get('Discriminator')
self.comment = fragment_as_dictionary.get('Comment')
self.order = Fragment.order self.order = Fragment.order
Fragment.order += 1 Fragment.order += 1
@@ -33,8 +42,6 @@ class Fragment:
return ( return (
self.current_english == other.current_english and self.current_english == other.current_english and
self.current_japanese == other.current_japanese and self.current_japanese == other.current_japanese and
self.new_english == other.new_english and
self.new_japanese == other.new_japanese and
self.discriminator == other.discriminator self.discriminator == other.discriminator
) )
@@ -52,6 +59,9 @@ class Fragment:
if self.discriminator is not None: if self.discriminator is not None:
retval['Discriminator'] = self.discriminator retval['Discriminator'] = self.discriminator
if self.comment is not None:
retval['Comment'] = self.comment
return retval return retval
def merge(all_translations: dict[str, Fragment], fragment: Fragment): def merge(all_translations: dict[str, Fragment], fragment: Fragment):
@@ -66,7 +76,7 @@ def merge(all_translations: dict[str, Fragment], fragment: Fragment):
else: else:
raise Exception(f"Warning: non duplicate item existing:{existing_item} new: {fragment}") raise Exception(f"Warning: non duplicate item existing:{existing_item} new: {fragment}")
en_mode = False
in_folder = "text-edits" in_folder = "text-edits"
@@ -81,7 +91,7 @@ for filename in files:
with open(path, encoding='utf-8') as f: with open(path, encoding='utf-8') as f:
chapter_list_dict = json.loads(f.read()) chapter_list_dict = json.loads(f.read())
all_fragments.extend(Fragment(f) for f in chapter_list_dict) all_fragments.extend(Fragment(f, en_mode) for f in chapter_list_dict)
all_translations = {} all_translations = {}

View File

@@ -8,6 +8,20 @@ use inflector::Inflector;
use log::*; use log::*;
use simplelog::{TermLogger, TerminalMode, ColorChoice,Config}; use simplelog::{TermLogger, TerminalMode, ColorChoice,Config};
fn try_absolute_exe_path(exe_name: &str) -> std::ffi::OsString
{
if let Ok(maybe_path) = fs::canonicalize(format!("{}.exe", exe_name))
{
if maybe_path.exists()
{
println!("Successfully found abs path of [{}] at [{}]", exe_name, maybe_path.to_string_lossy());
return maybe_path.into_os_string();
}
}
return std::ffi::OsString::from(exe_name);
}
fn main() -> ExitCode { fn main() -> ExitCode {
TermLogger::init( TermLogger::init(
LevelFilter::Trace, LevelFilter::Trace,
@@ -28,15 +42,15 @@ fn main() -> ExitCode {
}; };
// Check if python is correctly installed // Check if python is correctly installed
println!("Running 'python --version' to check if python is correctly installed..."); println!("Running 'python3 --version' to check if python is correctly installed...");
let result = Command::new("python") let result = Command::new("python3")
.arg("--version") .arg("--version")
.status() .status()
.expect("Failed to run python"); .expect("Failed to run python");
if !result.success() if !result.success()
{ {
println!("Python not found! via `python`. Make sure you:"); println!("Python not found! via `python3`. Make sure you:");
println!("- ticked 'Add Python to environment variables' in the python installer."); println!("- ticked 'Add Python to environment variables' in the python installer.");
println!("- can run 'python' in the console and get no error/the Microsoft Store does NOT appear"); println!("- can run 'python' in the console and get no error/the Microsoft Store does NOT appear");
println!("Failed to run python: {:?}", result); println!("Failed to run python: {:?}", result);
@@ -94,7 +108,7 @@ fn main() -> ExitCode {
fs::create_dir_all(&directory_data).expect("Failed to recreate directory"); fs::create_dir_all(&directory_data).expect("Failed to recreate directory");
// 0. check version // 0. check version
let output = Command::new("python") let output = Command::new("python3")
.env("PYTHONIOENCODING", "utf-8") .env("PYTHONIOENCODING", "utf-8")
.arg("scripts/AssetVersion.py") .arg("scripts/AssetVersion.py")
.arg(&assets) .arg(&assets)
@@ -112,7 +126,7 @@ fn main() -> ExitCode {
assert_eq!(unity, &version.trim()); assert_eq!(unity, &version.trim());
// 1. texts // 1. texts
let status = Command::new("python") let status = Command::new("python3")
.env("PYTHONIOENCODING", "utf-8") .env("PYTHONIOENCODING", "utf-8")
.arg("scripts/UnityTextModifier.py") .arg("scripts/UnityTextModifier.py")
.arg(&assets) .arg(&assets)
@@ -175,7 +189,7 @@ fn main() -> ExitCode {
_ => panic!("Couldn't identify version for arc {}", arc_number), _ => panic!("Couldn't identify version for arc {}", arc_number),
}; };
let status = Command::new("python") let status = Command::new("python3")
.env("PYTHONIOENCODING", "utf-8") .env("PYTHONIOENCODING", "utf-8")
.arg("scripts/TMPAssetConverter.py") .arg("scripts/TMPAssetConverter.py")
.arg("assets/fonts/msgothic_0 SDF Atlas_Texture2D.dat") .arg("assets/fonts/msgothic_0 SDF Atlas_Texture2D.dat")
@@ -200,7 +214,7 @@ fn main() -> ExitCode {
panic!("Couldn't find msgothic_2 font for chapter {} with config {}-{} at path [{}]", &chapter, &system, &unity, &font_path); panic!("Couldn't find msgothic_2 font for chapter {} with config {}-{} at path [{}]", &chapter, &system, &unity, &font_path);
} }
let status = Command::new("python") let status = Command::new("python3")
.env("PYTHONIOENCODING", "utf-8") .env("PYTHONIOENCODING", "utf-8")
.arg("scripts/TMPAssetConverter.py") .arg("scripts/TMPAssetConverter.py")
.arg("assets/fonts/msgothic_2 SDF Atlas_Texture2D.dat") .arg("assets/fonts/msgothic_2 SDF Atlas_Texture2D.dat")
@@ -222,7 +236,7 @@ fn main() -> ExitCode {
println!(); println!();
// 5. generate emip // 5. generate emip
let status = Command::new("python") let status = Command::new("python3")
.env("PYTHONIOENCODING", "utf-8") .env("PYTHONIOENCODING", "utf-8")
.arg("scripts/EMIPGenerator.py") .arg("scripts/EMIPGenerator.py")
.arg(format!("{}/sharedassets0.assets", &directory_data)) .arg(format!("{}/sharedassets0.assets", &directory_data))
@@ -236,10 +250,11 @@ fn main() -> ExitCode {
println!(); println!();
// 6. apply emip // 6. apply emip
let status = Command::new("AssetBundleExtractor") let status = Command::new("wine")
.arg("64bit/AssetBundleExtractor.exe")
.arg("applyemip") .arg("applyemip")
.arg(&emip) .arg(&emip)
.arg("output") .arg(".")
.status() .status()
.expect("failed to execute AssetBundleExtractor"); .expect("failed to execute AssetBundleExtractor");
@@ -253,14 +268,14 @@ fn main() -> ExitCode {
let cwd = "output".to_string(); let cwd = "output".to_string();
let files_to_archive = format!("{}/sharedassets0.assets", higu_ep_folder_name); let files_to_archive = format!("{}/sharedassets0.assets", higu_ep_folder_name);
let result_7za = pack_7zip("7za", &archive, &cwd, &files_to_archive); let result_7za = pack_7zip(&try_absolute_exe_path("7za"), &archive, &cwd, &files_to_archive);
let status: std::io::Result<process::ExitStatus> = match result_7za { let status: std::io::Result<process::ExitStatus> = match result_7za {
Ok(ok) => Ok(ok), Ok(ok) => Ok(ok),
Err(err) => match err.kind() { Err(err) => match err.kind() {
std::io::ErrorKind::NotFound => { std::io::ErrorKind::NotFound => {
println!("Warning: '7za' not found - trying '7z' instead"); println!("Warning: '7za' not found - trying '7z' instead");
pack_7zip("7z", &archive, &cwd, &files_to_archive) pack_7zip(&try_absolute_exe_path("7z"), &archive, &cwd, &files_to_archive)
}, },
_ => Err(err), _ => Err(err),
} }
@@ -278,8 +293,8 @@ fn format_checksum(checksum: Option<&String>, sep: &str) -> String
return checksum.map_or("".to_string(), |c| format!("{}{}", sep, c)); return checksum.map_or("".to_string(), |c| format!("{}{}", sep, c));
} }
fn pack_7zip(command: &str, archive: &String, cwd: &String, path: &String) -> std::io::Result<process::ExitStatus> { fn pack_7zip<S: AsRef<std::ffi::OsStr>>(command: &S, archive: &String, cwd: &String, path: &String) -> std::io::Result<process::ExitStatus> {
println!("[7-Zip] Running {} in working directory: [{}] and path: [{}]...", command, cwd, path); println!("[7-Zip] Running {} in working directory: [{}] and path: [{}]...", command.as_ref().to_string_lossy(), cwd, path);
Command::new(command) Command::new(command)
.current_dir(cwd) .current_dir(cwd)