文章列表

升級 Spring Boot WebClient SSL (Reactor Netty 1.2.6):重新配置 SSL 設定

科技新知
MacauYeah・2025-08-27

因為SSL provider 更新了的關係,好多 HttpClient / WebClient 設定SSL的部份都要重寫以免出現 deprecated 問題 reactor.netty.http.client.HttpClient 在 1.0.x, 中可以這樣自行設定SSL逾時的部份,但當中的spec.sslContext().defaultConfiguration 在新版本,例如1.1.x後就會出現 deprecated。 // deprecated version HttpClient.create() .secure(spec -> spec.sslContext(SslContextBuilder.forClient()) .defaultConfiguration(SslProvider.DefaultConfigurationType.TCP) .handshakeTimeout(Duration.ofSeconds(30)) .closeNotifyFlushTimeout(Duration.ofSeconds(10)) .closeNotifyReadTimeout(Duration.ofSeconds(10))); 觀看各大網站,都未有更新,唯有自行研究官方說明。 筆者撰寫本文的時候,netty 發行版本為 1.2.6, 1.3.0 還里程碑(M6)的階段。所有參考皆來自1.2.6版本,實際上我們要使用新的後綴為ContextSpec類,看Class名應該有分http 1.1, 2, 3的版本,筆者就試用最基本的http 1.1。Http11SslContextSpec, (有條件的朋友可以試用Http2SslContextSpec, Http3SslContextSpec) import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.client.HttpClient; import java.time.Duration; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.http.client.reactive.ReactorClientHttpConnector; //... Http11SslContextSpec http11SslContextSpec = Http11SslContextSpec.forClient(); HttpClient httpClient = HttpClient.create() .secure(spec -> spec.sslContext(http11SslContextSpec) .handshakeTimeout(Duration.ofSeconds(30)) .closeNotifyFlushTimeout(Duration.ofSeconds(10)) .closeNotifyReadTimeout(Duration.ofSeconds(10))); WebClient webClient = WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); //... 雖然這個寫法來看netty 1.2.6,但似乎1.1.x 通用。大家有需要可以交互測試一下。 Reference netty 1.2.6 http-client-timeout 的設定 netty 1.1.30 timeout-configuration 的設定 netty 1.2.6 java api doc netty release version 更多筆者的程式開發分享,見請 github

Spring Boot Web App 更新期間的維護模式:從唯讀到全鎖的解決方案

科技新知
MacauYeah・2025-08-25

在營運 Web App 的時候,雖然我們有 Docker / K8s 可以滾動更新,但難保用戶在更新的過程中,有一半訪問去到了舊版,另一半去了新版。如果可以,Web App 本身自帶維護模式,可以自我判斷什麼時候應該忽略新的訪問,當然最好。但要做到這一點,前期需要很多規劃。狠心一點,可以直接關掉對外的服務,讓用戶無法訪問。 但在另一些情況下,例如升級/搬遷的情況,下線時間比較長,完全關掉服務並不是一個很好的方向,我們至少還可以提供唯讀的選擇。而且這個可以從資料庫出發,讓 Web App 少處理一點邏輯。 如果 Web App 背後的資料庫是 MSSQL 或 MySQL,唯讀這件事應該是簡單的,只要你把 service account 的權限改變就好。但如果你用Oracle,就要想想辦法。 筆者想到的方法,暫時有兩個。第一個就需要大家寫寫 Script ,一口氣把所有 Table 給鎖起來。例如: 第二個,就是生成一個新的唯讀 User schema,給他所有Select的權限。然後更新 Web App 使用那個唯讀 User schema存取資料。 兩個方法有什麼差異呢? 前者就全部鎖起來,沒有任何一個資料庫用戶可以改寫資料。如果你的業務沒有差異性,全部一起封起來就完事。但如果你只想 Web App 轉成唯讀,但其他背景程式還可以執行更新。那你就只能用後者了。但後著也不是百分百的完全無痛,至少你 Web App 要支援登入與操作的 Schema分離。 例如用Spring boot JPA的話,可以在 application.properties 可以讓登入及操作的Schema不一樣。 spring.datasource.username=READ_ONLY_USER spring.jpa.properties.hibernate.default_schema=ORIGINAL_SCHEMA 又或者在 java 層面指定。 @Table(schema = "ORIGINAL_SCHEMA") 這看上去,是很有彈性的。但其實也是有些局限。如果你本來的JPA有寫特制的 JPQL 或 Raw Query,又或者你在Java層面加了 @Subselect,由於這些都是程式原作者所 hard code 的,JPA沒法幫你改寫。改來改去,可能還是前述寫Script的方法,一口氣把所有 Table 給鎖起來實際一些。 Reference 更多筆者的程式開發分享,見請 github

Galera 4 (Mariadb cluster) 的冷開機

科技新知
MacauYeah・2025-08-20

前次我們介紹了 Galera 4 在Ubuntu 24的架設方式,這次我們來補充一個最常見的問題Cold Start 冷開機 cold start 平常, Cluster 中只有其中一個 node 需要更新重啟,基本上所有節點回覆正常後,都可以互相通訊。而有些情況,例如斷電問題,需要所有節點全數關機,那麼 Galera cluster 就需要一定的方式重啟系統。那是一些狀態的保護機制,因為在全關機後再同步,系統不知道哪台機才有最新的狀態,它也不敢貿然同步(因為正常使用下, Galera cluster 只有兩台機也會開步)。所以需要人手介入,指定以某台機作為 cluster 的起始點。 舉個最簡單的例子,前述三台機 pocdbnode3 , pocdbnode2 , pocdbnode1 順序關閉,那麼 pocdbnode1 應該就會有最新的資訊。 在ubuntu中,可以查看 /var/lib/mysql/grastate.dat 中的 safe_to_bootstrap:是否為1。如果是1,代表當初它有最後的 transaction ,以它為起始點重新起 cluster。 $ cat /var/lib/mysql/grastate.dat # GALERA saved state version: 2.1 uuid: 0c38b6dd-7bdb-11f0-a4dd-1f4be36a6ea9 seqno: -1 safe_to_bootstrap: 1 我們使用galera_recovery, galera_new_cluster, 就可以把該機器重新救起mariadb process。 $ galera_recovery WSREP: Recovered position 0c38b6dd-7bdb-11f0-a4dd-1f4be36a6ea9:11 --wsrep_start_position=0c38b6dd-7bdb-11f0-a4dd-1f4be36a6ea9:11 $ galera_new_cluster 然後其餘兩個 node 可以直接重啟 mariadb 服務 # node 2 $ systemctl start mariadb # node 3 $ systemctl start mariadb Reference Getting Started with MariaDB Galera Cluster 官方文件 How to Set up MariaDB Galera Clusters on Ubuntu 22.04 How to Bootstrap MySQL or MariaDB Galera Cluster – Updated : 還有比較複雜的救機狀況,例如:safe_to_bootstrap全為0,即是可能是全部node都沒有好好地關掉,就掛了。大家有需要可以看看這個link的解決

Spring boot 10 - openapi 生成器 - spring boot java client

科技新知
MacauYeah・2025-08-19

之前我們在介紹Spring Boot Web 調試工具 ,就試安裝 openapi 相關的元件。其實 openapi 並不單是為了提供 swagger 測試介面,它主要是提供一個描述的方式,讓我們針對一個特定 openapi 文件,生成對應的 api server 或 api client 接口。也就是,如果 server 方有提供該文件,道理上可以經 openapi 的工具,生成一個可以直接訪問 server 的 client library。本節,可以沿用之前的 spring boot web api doc ,為它產生一個client library 作為實驗。 在生成 client library 之前,我們還需要一個工具 openapi-generator-cli 。最簡單的取得方式,就是經過 npm , 在你需要生成 client library 的專案中,安裝你需要的 openapi-generator-cli 版本。 npm install @openapitools/openapi-generator-cli 那怕你不是使用 nodejs 作為開發,也可以經過這個方法安裝。它只提供使用 cmd 指令的捷徑。 生成 Java Client Library 我們先把 backend server 起好 cd somewhere && mvn spring-boot:run,然後使用 openapi-generator-cli 去生成以 java spring boot 3 為底的 client library 。 npx openapi-generator-cli generate \ -i http://localhost:8080/v3/api-docs \ --api-package io.github.macauyeah.springboot.tutorial.openapiclient.api \ --model-package io.github.macauyeah.springboot.tutorial.openapiclient.model \ --invoker-package io.github.macauyeah.springboot.tutorial.openapiclient.invoker \ --group-id io.github.macauyeah.springboot.tutorial \ --artifact-id spring-boot-web-api-open-api-client \ --artifact-version 0.0.1-SNAPSHOT \ -g java \ -p useJakartaEe=true \ -p useSpringBoot3=true \ --library webclient \ -o spring-boot-web-api-open-api-client 生成的 source code 就像是 spring-boot-web-api-open-api-client ,具體的使用方式,可以看看測試用例 ApiControllerApiTest.java private final ApiControllerApi api = new ApiControllerApi(); @Test public void postDateQueryTest() { // default call ApiDateRequest apiDateRequest = new ApiDateRequest(); apiDateRequest.setInputDate(OffsetDateTime.now()); LOG.debug("default web client postDateQuery:{}", api.postDateQuery(apiDateRequest).block()); // replace webClient in ApiClient if you have special auth config on // webClient, you can also change basePath during new obj creation ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat()); mapper.registerModule(new JavaTimeModule()); WebClient webClient = WebClient.builder() .codecs(configurer -> { configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper)); configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper)); }) .build(); ApiControllerApi api2 = new ApiControllerApi( new ApiClient(webClient) .setBasePath("http://localhost:8080/")); LOG.debug("create api2 by local web client postDateQuery:{}", api2.postDateQuery(apiDateRequest).block()); // use webClient directly String response = webClient.post().uri("http://localhost:8080/api/record").bodyValue(apiDateRequest).retrieve() .bodyToMono(String.class).block(); LOG.debug("request by local web client postDateQuery:{}", response); } 上述例子中,如果大家沒有任何特殊要求,其實經過 api.postDateQuery(apiDateRequest).block() 就完成了。有需要改 api endpoint 的,只要生成新的 ApiClient 並設定 basePath new ApiClient().setBasePath("XXXXXX") 就好。真的要加入更多權限設定,就需要生成新的 ApiClient 並設定 webClient new ApiClient(webClient) 這個生成的 Java Client Library 道理上還是要經過 maven 等打包,變成 jar 檔,才能被其他 Java 專案所引用。筆者就建議大家直接把成生的視為獨立的 module (sub module) 存放,其他專案就以 maven dependency 的方式引用。想要混合現有專案,動態生成專案內某些 java package,暫時不太可行。因為它也有大量的 dependency ,交由 openapi-generator-cli 自己管理會比較好,它們升級時,你也可以完整升級。 openapi-generator-cli https://github.com/OpenAPITools/openapi-generator-cli spring-boot-web-api-open-api-client

重入膠坑 11 |素組黨的水口極限

手機‧電玩
MacauYeah・2025-08-09

陸逐地,筆者分享了一些高達模型回鍋的心得近一年,素組的手法實驗也做得七七八八了,再推過,就是向噴塗進發。 素組主要是考慮水口處理和補色的問題,而水口更是入門模型的重症。筆者就再在這一篇做個水口處理的總結,比較不同的處理方式的效果。 神剪 最簡單的方式。做MG的話很夠用,不過做HG,有些水口的位置很奇怪,看著就難受,而且會影響補色。 神剪+打磨(低目數至高目數砂紙) 有效消除明顯水口的方式,最後只會留有白點或深色的一點。看個人需求,是否可以無視那「一點」。另外因為打磨量多,塵土飛揚,需要注意環境影響。 神剪+打磨(低目數砂紙+筆刀水平刮) 能除去水口,但平面不平整,很多時會見到刮痕,比較不可能無視。筆刀刮出來的碎屑比較大粒,沒有那麼大塵。 神剪+Marker補色遮蓋 不能遮蓋水口,因為有高低面,造成積漆,所以會很奇怪。跟只有神剪的效果差不多,非常不推薦。 神剪+打磨(低目數至高目數砂紙)+消光 更大程度模糊水口剩下的那「一點」。工作量雖多,但效果算是上好。 神剪+打磨(低目數砂紙+筆刀)+消光 水口、刮痕會被模糊,正面看就看不到刮痕,側看還是很明顯。 神剪+打磨(低目數砂紙+筆刀)+Marker補色遮蓋 因為筆塗漆面比較厚,水口及筆刀的刮痕基本都可以被覆蓋,平面不平整的問題就沒有辦法解決。另外筆塗會引入筆痕、塗裝出界、刮漆的問題。 神剪+打磨(低目數砂紙+筆刀)+Marker補色遮蓋+保護漆 保護漆可以減少前述刮漆問題,仍需無視平面不平整的問題。如果想更進一步防止刮漆,需要向底灰進發。底灰已超出了素組的範圍,就不作太多描述。 神剪+打磨(低目數至高目數砂紙)+Marker補色遮蓋+保護漆 理論上是最優解,工作量也是最多的。 該選擇什麼? 初入門,可能「神剪」就夠。因為工作量最少,效果最顯注。 進一步就是「神剪+打磨(低目數+筆刀)」,優點亦是工作量沒有多很多。同時可以挑戰刻線滲線,工具和流程也沒有很大衝突。 實在像筆者那般,接受不了那「一點」,就「神剪+打磨(低目數+筆刀)+Marker補色遮蓋。筆刀比高目數打磨省時,Marker也可以完全遮了那「一點」。 至於為何不用消光漆呢? 首先,噴鑵消光的成本是很高的,想好好地逐個部位噴,很快就會用完。 第二,消光的作用是讓高達模型的那層膠面不再發生,看起來沒有那麼玩具感。而我們前述經打磨和補色(什至是色差補色),原本顏色已經豐富好多,使用消光漆的差異唔太明顯。 第三,就是後期修補更難,消光漆想想地清理,是非常之煩。一定要確保各項工序做完,例如修正出界、滲線不乾淨、重滲線問題,再去上消光漆。不過如果全部做足了以後,可能已經沒有很想消光的必要。

生活AI 應用筆記

科技新知
MacauYeah・2025-07-22

上週六(7月19日),筆者參加了聖公會的一門講座「AI時代,父母的教養實戰新教程」,學習如何利用AI輔助小朋友的教育。雖然課題如此,但課堂還是以感受AI的使用方式為主,之後大家就好好利用AI這個知識庫去激發新思維。課堂上,文字、語音、動畫都有示範,但筆者感受到文字AI的部分最為深刻。 在過去一兩年,筆者曾略微使用AI,但即使在DeepSeek出現後,筆者仍覺得幫助有限。這主要是因為筆者身處科技行業,AI給出的答案不夠精準,難以協助開發,還可能導致一堆無法延續的結果,因此筆者甚少使用。然而,上課的主題並非針對本業使用AI,而是探討如何利用AI為生活注入更多新感受。 AI或許無法取代專業,但可以幫助你引入跨界元素,讓思考模式或你的作品更加多樣化。課堂中,學員將自己創作的家書放入AI,請它協助轉換成不同年齡層的人用詞、改編為劇本或變成辯論議題等。當然,並非每個方向都能產生合理的結果,例如家書轉為辯論,明顯會顯得不合適。但由於轉換的成本低,你可以透過少量提詞,得到多樣不同的呈現效果,激發新的思維。這就像在創作前,你可能會參考大量同類型的作品,去取得靈感。 筆者也簡單分享一些使用文字AI創作的方向,希望大家能有所收穫。 首先,準備好自己的原稿,這個原稿必須是由自己親自起草的,而非AI生成的主題方向。起草時,不必過於拘泥於前後文法,只需有一個大概方向即可。 將原稿交給AI,請它幫忙修改。AI會協助你修正一些口語或錯字問題。 嘗試請AI給你一些建議,或者請它幫你補充段落。筆者認為,請AI給建議會更好一些,因為有時補充段落可能會顯得過於機械。 除此之外,文字AI在日常生活中還做得不錯的實例 整理文章重點,重新以不同的方式演繹 整埋文章重點,筆者在大學的教育中,就經常看到以條列重點去取得原本書的教學方式。所以針對中小學教育,或新知識的學習,都可以試試用AI來整理大意,提升學習效率。 更強的是,如果你還是看不懂,可以叫AI以更多例子,深一點或淺一點去解釋一次。 禮物準備 有時物輕情義重,如果你身邊的親友很重儀式感,那麼使用AI的搜集及變化能力來幫你多樣化禮物的準備,相信可能為你加入更多新元素。 計劃旅行 計劃旅行,過去一般都參考他人的行程分享。過去就一篇一篇地逐篇閱讀,個人歸納。現在你可以先問AI,再去覆核。過去自行搜尋的方式,可能會被一些旅遊網站的文章所佔據,而現在改用AI,配合不同的提詞(prompt),你還可以多一些不同的參考角度。 註:本文僅使用AI修正用字,並未生成任何插畫或議題。

Docker 101 - 為何要做成Docker (Container - 容器化)

科技新知
MacauYeah・2025-07-21

筆者更新了之前的Docker入門筆記(https://github.com/macauyeah/VMDockerNotes/blob/main/DockerConcept101CN.md),順便補充了一些內容。如果各位讀者還在糾結要不要進行容器化,可以看看這些特性有沒有讓你心動。 Container - 容器化的便利 1. 做到隔離效果 傳統上,同一機器安裝不同的 lib / dependency ,可能出現衝突。在 docker 的環境下,不同 container 之間可以隔離開,除了是網路之間出現引用關係的衝突外,動態庫的衝突就沒有見過。一般處理好 Persistent Volume 的考量,單機下是沒有什麼問題的。 2. 遷移的過程比較簡單 傳統上,要把程式從一台機器搬到另一台機器,要預先安裝好相關的 lib / dependency 。但使用 docker / container 後,只要 docker 版本相容就好。docker image 本身,就已包括所有的 lib / dependency 。另一個常見的傳統問題,就是 Linux 檔案的擁有權問題,特殊情況下,新機同一個 user 的 ID 編號也不一樣,可能要手動恢復權限。如果是 container 的 bind mount 檔案,只要使用 tar command (`tar --same-owner -xvf file.tar`)保留權限解壓就好。 3. 垂直水平擴容 因為有隔離及遷移方便的優勢,原本的機器達到上限,可以隨時換到其他機器上,修改對應的用戶入口就可以了(或更改DNS,可以更無縫連接)。一台機器不夠,亦可以多台機器一起來。即使不使用 docker swarm / k8s 方案,有傳統的 proxy gateway 再加單機的 docker ,就可以做到分流的效果。 當然使用 docker swarm / k8s 才是正解,可以更簡化 proxy gateway 的設定。而傳統的分佈式問題,例如 Share Storage 等,其實就沒有簡化到,但也沒有增加難度。所以大家若考慮擴容的問題,更適合考慮使用 Container 的方案。 筆者總結這兩三年來的使用經驗,只要大家一直有用開Linux,其實單機容器化不太難,頂多就是配置外置Persistent Volume / Share Storage會帶來不習慣。而大家也可以想,Storage 這問題,是隨時隨地佈署應用程式的不可或缺的思考方式。Docker 沒有帶來更多的麻煩,而是帶來更多標準化的應用,例如傳統的NAS / NFS,也是這個Storage問題的其中一個解法。

Swarm mode 上線 7 - load balancer | 反向代理 (2)

科技新知
MacauYeah・2025-07-18

前幾天,我們就使用traefik做了個最簡單的http反向代理。 做完上述的使用驗證後,我們可以正式開始看官方的例子,該例子加入了SSL,這就更充份地體現反向代理的用途。 官方教學連結 官方的yaml也很長,筆者實測了一個簡化版本。 services: traefik: image: traefik:v3.4 ports: - target: 443 published: 443 protocol: tcp networks: - traefik_proxy volumes: - /var/run/docker.sock:/var/run/docker.sock:ro configs: - source: dynamic-tls.yaml target: /dynamic/tls.yaml secrets: - source: certs-local.key target: /certs/local.key - source: certs-local.crt target: /certs/local.crt command: - --api.dashboard=true - --log.level=INFO - --accesslog=true - "--providers.file.filename=/dynamic/tls.yaml" - --providers.swarm.exposedByDefault=false - --providers.swarm.network=traefik_proxy - --entrypoints.websecure.address=:443 - --entrypoints.websecure.http.tls=true deploy: replicas: 1 placement: constraints: - node.role==manager whoami: image: traefik/whoami networks: - traefik_proxy deploy: labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)" - "traefik.http.routers.whoami.tls=true" - traefik.http.services.whoami.loadbalancer.server.port=80 networks: traefik_proxy: name: traefik_proxy driver: overlay attachable: true configs: dynamic-tls.yaml: file: ./dynamic/tls.yaml secrets: certs-local.key: file: ./certs/local.key certs-local.crt: file: ./certs/local.crt 餘下的就照跟官方設定 生成cert file。(或大家有正式的證書,就可以免去這一步。) mkdir -p certs openssl req -x509 -nodes -days 365 -newkey rsa:2048 \\ -keyout certs/local.key -out certs/local.crt \\ -subj "/CN=*.swarm.localhost" 指向cert的動態設定檔。 tls: certificates: - certFile: /certs/local.crt keyFile: /certs/local.key 然後我們就可以這樣測試 curl -v -k -H 'host:whoami.swarm.localhost' 筆者在一開始時,始終無法設定 dyanmic/tls.yaml ,其實是筆者誤會了 traefik 的讀取方式。本個例子中,traefik 其實會動態讀取 swarm 及 file provider 的設置,而dyanmic/tls.yaml是經過file provider的方式生效。也就是 traefik-ssl.yaml 中的"--providers.file.filename=/dynamic/tls.yaml"。 本個例子與官方例子最大的不同,是官方的cert, tls, 是直接使用bind mount的方式存取,如果你有多過一個manager,這個方式不太有效。本文就用了swarm config及swarm secret,方便多個manager自動配置。不過swarm config及swarm secret都有個缺點,若要更新它們的內容,就必需要重命名(例如dynamic-tls.yaml=> dynamic-tls.yaml2) ,否則swarm不允許發佈。 完整 yaml 請見 github

Swarm mode 上線 7 - load balancer | 反向代理

科技新知
MacauYeah・2025-06-30

前述我們介紹了負載平衡器的概念,也使用了nginx作為反向代理,管理網絡訪問,分流到對應的服務上( docker service )。 nginx是穩定的,大家初次使用 reverse proxy (反向代理),請選擇它,因為相對簡單,也易於在單機上做對比測試。 而nginx有個麻煩的地方,就是每次加 docker service,都需要更改 nginx 的設定。我們service 越多,config檔就越長。一個不少心,某些設定有衝突,就會讓 nginx 無法重起。 所以,我們在一定規模後,就需要改用自動化的反向代理。 traefik 就是其中之一。所恨的是,官方沒有提供 swarm 的範例,需要自行摸索。幸好筆者找到一個Github網路資源,bluepuma77 traefik-best-practice,內有一個traefik在docker swarm上的基本設定,足以解開筆者的某些謎思,至少可以讓筆者進行使用驗證。 bluepuma77 提供的範例可能還有些複雜,筆者就再簡化一下,讓大家可以從最基本的環境中開始。 下述 docker service 中 traefik: 自動偵測 swarm 中,有那些其他 service 需要經過traefik 代理。 whoami: 一個官方提供的簡單版http 回應,它正常可以回應 http 80的請求。 有一些重要的地方需要特別說明: 需要設定 --providers.swarm.exposedByDefault=false,不然traefik自己也需要定義反向代理的port。設定了這個,也可以讓 swarm 中某些 service 得以被忽略。有需要經 traefik 對外的,就在 label 下設定 traefik.enable=true 需要設定--providers.swarm.network=proxy,swarm中也需要有該網絡的存在。不然traefik 沒有預設的網絡可以走。 現時 docker service 使用是的 ingress mode,方便 traefik service 可以在不同的 manager 上遊走。測試時需要注意使用 ipv4 ,例如 curl 需要指定 ipv4 的 ip 即curl -v -H 'host:whoami.localhost' http://127.0.0.1/ ,若直接使用 whoami.localhost ,有機會會指向 ivp6 , ingress mode 就接不到。 Reference: https://github.com/bluepuma77/traefik-best-practice/blob/main/docker-swarm-traefik/docker-compose.yml https://doc.traefik.io/traefik/routing/routers/#path-pathprefix-and-pathregexp

重入膠坑 10|JMS(集模社)的馬克兔作品分享

手機‧電玩
MacauYeah・2025-06-26

回鍋模型制作已經好一段時間,亦做了不少的嘗試。但如果大家覺得新嘗試有點怕怕,可以試一試以國産KO(高仿)作為實驗對像。 筆者並不支持KO,因為質量真的有差,但以練手的角度出發,要做很多白老鼠實驗,那麼KO的價錢絕對是一個合適的選擇。可能有朋友會問,做實驗為何不使用廢件?廢件做一些基本實驗是可以的,例如切削、顔料,使用單件就可以做到。但如果要做流程實驗,廢件很難折開重來。比例實在的,還是從零剪件容易一點。實驗的流程可能是板噴、局部取件、打磨+刻線+滲線等。 筆者最近就開了一盒 JMS(集模社)的馬克兔 21世紀配色,主要試一下加深刻線+打磨+滲線配色+水貼的流程。 先上作品圖 外貎很可以 工具 刻線:0.15刻線刀 打磨:400 600 800砂紙、陶瓷推刀 滲線液:田宮滲線液 水貼:KO自帶的水貼 流程 因為水貼原因,原本有打算用司特力的水性滲線液,但在個別區域試過後,就知道會被水貼的水引流的問題,所以馬上改回田宮的琺瑯滲線液。 加深刻線部份,想少錯,就用刻線膠帶,不然出界就要用打磨的方式修正。筆者就懶得貼,所以不少地方都有打磨的痕跡。修正時,感覺上先用推刀刮,再使用600、800號砂紙打磨,後期再消光漆,就已經足夠。有些地方,什至只用推刀,感覺上差異也不大。 滲線液的部份,本次試用黑色,作為大反差配色。個人覺得在馬克兔 21世紀下,效果配色不差,可以跟軀幹部份相對應。 至於JMS品質,真的是練手的好選擇,組合度OK。但我們不能要求關強度,對把玩有要求的朋友請勿嘗試。

如果把一款課金手遊當成單機speedrun遊戲玩會怎樣?04

手機‧電玩
MacauYeah・2025-06-25

ZZ、Seed 2 Lv40 起跳 個人感覺跟之前W差不多,不易,但也不難,原本有經過W的提升,相信大家的自由部隊應該很有實力。再加上ZZ和Seed 2 可以沿用Z和Seed的機體,原本遊戲機制,限制你的出場機體,所可能的影響相對少很多,大部份都可以自動去打。間中有不滿三星的關卡,再強化機體重新挑戰應該都可以達成。 水星的魔女 Lv50 起跳 經過ZZ後,主線關卡後段開放,玩家可以自由選擇不同系列。筆者就選了水星的魔女系列。水星前半關卡不能說是很難,但就是沒法自動取得三星評價,致使本系列SR機體難以開發。那怕你把系列機體升級到50、70,自由系列升級到滿級(80, 90, 100),自動操作都只可以取得二星。主要是關卡中敵方雜兵太強,系列部隊只有送頭的份。筆者回頭重複挑戰,必需轉為手動操作,調配自由組隊(即2隊)才有等級優勢。 為了之後的其他關卡團積優勢,筆者進一步強化自由組隊的機體,魔女系列真的得過扯過。 00系列 Lv50 起跳 筆者自由組隊的機體已有5台主力基本等級升滿,(武裝及突破未升)。在00前期關卡,攻擊力還可以,可以一發攻擊收掉一個敵方機體。但後期則出力不足,自由部組隊也需要協力才能收走對方。更嚴重的是,開自動模式的話,可能會出現我方重要機體被擊破而Game Over的問題。為了穩定,基本也要手動操作過關。00開發路線中,也因為沒有取得足夠的開發資源,筆者在後半亦只有開發出四小強中的三台,實在有些勉強。如果未有遊玩的讀者們,可以試一下別的系列,團一下機體突破資源。 機體數值 雖然每個系列最後都可以最後SSR機體,但因為素材取得難,需要不斷重打困難關卡,而且困難關卡無法用免費/付費課金石去回覆略過次數,所以真要升級只能逐關掛機刷。筆者現況,SSR最多只可以突破至一星(主線首次通關數素+困難關卡的首次完成獎勵),但這個時間成本相當,所以有必要嘗試替補策略。 筆者育成機體不多,就以泛用性以前題下,用兩台seed系機體作為測試 SSR完美突擊,初始90級上限,一星突破,海陸空三地適用。 SR自由,初始80級上限,二星突破,海陸空三地適用。 只看攻擊力的話,SR自由有高一點點,勉強可以作為替代戰力。但防禦力及機動力明顯有差,自動模式下抗壓性不高。需要手動打Combo,以減少自動分散攻擊引發的被反擊問題。日後筆者可能會以其他系列作實驗,粗略計算一下二星SR及一星SSR的時間成本比較。

重入膠坑 9 |加深刻線

手機‧電玩
MacauYeah・2025-06-20

之前就為大家介紹過,想有效率地消除Gunpla山積,事前計劃好一個概定的流程,絕對是件很重要的事。筆者亦有分享一過自己使用取件表的效果,對素組黨是有一定的好處。有時筆者亦會使用極簡版的素組流程,完全制作局部的部件,再進行下一部份,就只需兩個零件盒就夠。 最近,筆者就想再次升級,進行刻線加深再滲線,然後補色,那麼之前極簡版的步驟就不完全適用了。主要因為滲線部份,依據刻線的熟練度及不同顏料的特性,某些步驟要提前,關於顏料的部份可能一次性地使用會更佳。 簡單回顧之前素組流程:剪件→修件→打磨→組合→滲粗線→補色→保護漆。 現在,我們想利用刻線的方式為更多高低面滲線,至少要在完全組合之前就去刻。又因為刻線容錯率問題,刻線出界時,很多時需要利用打磨的方式修正。而且打磨之後,因為表面不夠光滑,水性滲線液比較難以擦乾淨,所以就在打磨之前滲線,可以避免一些奇怪的情況。 現在可以改成:剪件→修件→刻線→滲線→打磨→組合→補色→保護漆。 如果你的是琺瑯漆滲線液,只要刻線夠深,比較沒有擦不乾淨的問題,所以你可以考慮以下組合。 琺瑯漆滲線流程:剪件→修件→刻線→打磨→組合→滲線/補色→保護漆。 到底是先滲線還是先補色,就視乎補色顏料的附著力和互相溶解的問題。道理上補色marker附著力不強,怕在抹滲線漬時同時抺走marker,可能先滲線後補色會好一點。 最後,就再補充一下極簡步驟中,想完整完成一個局部區域再去下一步,這個想法理論上可行,只要大家不計較滲線液、水性漆的消耗率(利用率),是可行的。 全件修件後,之後再全件滲線,這樣滲線性就一次性地使用。這樣可以減少滲線性濃度不一致的問題,也差少在攪拌時出現的浪費(司特力的原裝瓶實在很易出意外,不如田宮的穩定)。補色方面也是,即使是經過調色,如果可以一次性地使用,就可以減少色差和消耗。如果大家不在意這些問題,也就不需要全件完成才進入下一步。即使在全件規劃的情況下,有時還是會因為失誤,而需要反工。