文章列表

星穹鐵道:模擬宇宙系統簡介

手機‧電玩
MacauYeah・2024-02-22

因為模擬宇宙是遊戲中一個很重要的資源獎勵來源,所以就來全面的講講它的運作方式。 模擬宇宙玩法 模擬宇宙分為多個世界,目前筆者已知的世界有八個,分別對應遊戲序章、一章、二意的地圖和敵人,除了Boss外的敵人種類都有一定隨機性。第三世界至第八世界需要根據主線遊戲進度而開啟。 積分獎勵 每次挑戰不同世界都有積分獎勵,即使沒有到達終點也會有積分。第三世界開始有不同的難度選擇,積分當然也會因為難度提高而變得更高。 每週積分到達上限後,可以取得重要的行跡升級素材 - 【命運的足跡】。而模擬宇宙一週積分會重置一次,也就是一週可以取得一個。這是角色養成後期的必要道具,只能經過不同的獎勵途徑取得(例如無名勳禮、餘燼兌換,但因為週期更長,所以暫不推薦)。 敵人道具掉落 平常角色行跡升級素材,需要經過刷普通敵人取得,同樣原理,刷模擬宇宙不同世界也可以取得。最大差異是,普通敵人刷新率受時間限制,而模擬宇宙重新挑戰就可以一直刷。要變新角色的話,刷模擬宇宙是一個可行的選擇。 積分和道具掉落獎勵也當然會因為難度提高而變得更豐厚。 命途、祝福 在主線中,不斷地提及這個遊戲中很有多個古神之類的存在。而這些神明,在模擬宇宙中就以【命途迴響】、及【祝福】來為玩家加Buff。 玩家在進行世界時,選擇角色時,亦要選擇命途。然後每次戰鬥後,就可以在三個隨機祝福中選一個。當目標命途底下對應的祝福齊夠六個以後,就可以取得命途迴響,一個更強大的Buff。指定祝福越多,命途迴響有更多額外功能,所以模擬宇宙中的Buff有很大的隨機性。 我們要降底隨機性,就只能通過有限度的置換來選取掉落的祝福。 解鎖一定量的命途、祝福,也可以取得一次性的收集進度獎勵,所以去到第七、八世界,你就會開始糾結,該選新的祝福但沒有命途加成,還是先加成後收集? 奇物 更隨機的道具,筆者認為大部份都是Debuff,因為它很大機會嚴重地干擾命途和祝福的配搭。因為同樣有收集進度獎勵,所以第一次遇到的話,也是要取舍。 筆者建議就先收集,後通關。因為低機率的物品真的百年難得一遇。 沉浸獎勵 一定難度開始,在挑戰過程中會出現沉浸獎勵,可以使用【開拓力】或【沉浸器】來兌換。它也是取得後期遺器的重要來源。

git 分支整合問題

科技新知
MacauYeah・2024-02-20

不知道大家的開發團隊、專案規模有多大,但只要系統或程式已發佈,同時又要做維護更新,git 庫都至少會有兩條分枝: 新功能 - main / feature 最新的穩定發佈版本 - Release / v1.x.x 最好的情況下,在開發完新功能之前,穩定版本都沒有需要緊急修正的地方,開發者可以專心開發新功能(main / feature)。然而這個情況並不能經常維持。 情況1:有Bug要馬上修正 最常見到的情況,就是穩定發佈版本有瑕疵,可以經過小修小改來止血,由v1.x.x ⇒ v1.x.y,這些可能對用戶來說,是沒有太大感覺的改動。不過對於開發流程,就免不了由v1.x.y整合(merge)回main時,出現修改衝突的問題。 建議 若屬於日後不再需要的改動,不需於整合到main中, 當然什麼都不用做。但若屬於必要的更新,就需要早早整合到main中。整合雖然痛苦,但延後整合沒有好處。以筆者的經驗,每次整合時有衝突,而越早整合越有條件知道該取用自動混合的那個版本。以整合工具的語言來說,就是更容易的作出use mine / use theirs / edit。 情況2: 不同功能之間有衝突 上述情況1,已經算是可控的。主要因為穩定發佈版本都只會接受小修小改,大改都會直接在main中開當為新功能開發。當你有多個很重要的功能在不同時期被提出,而有些功能你沒有信心在下個發佈中提出,你就會選擇以獨立分支來實現不同的功能,最後選擇信心度高、權重也比較高的功能來發佈。這樣的好處是你可以有限時間先完成最必要的功能,但問題是多個功能分支之間,更容易地有衝突,後期也需要很廢心力地整合。 建議 少做資料夾層面的改動,因為git rename的功能並不是萬能的,會令很多git自動選擇版變得不可讀。筆者的經驗,就是錯把後端和前端的資料夾混在一起,令後端的一些重命名影響到前端。前端也因為有重寫的需要,對資料夾結構大改。最後結果就是很多看不懂的git自動選擇版。有一些有選對,但有一些就選錯。 可以做一些事前處理,來減經痛苦。在筆者的資料夾問題情境,在把後端將要整合的多個commit中,挑選最早前沒有命名問題的commit先整合一次。然後前端先手動模擬後端的人工命名,自行commit一次,最後再把後端剩餘的commit再做整合。這個做法不是完全解決問題,但至少可以讓use mine / use theirs / edit更新易理解。 而另一個建議是,縮短發佈週期,逼使其他開發中的功能越早做整合,也逼使每個功能不要做太大規模的改動。如果真的做大規模改動,就要有心理準備要多次重要的整合。 情況3: 多個穩定發佈版本需要同時維護 若然大家面對的工作規模真的很大,同時有多個版運行版本,就如gitlab,每一個月都有一個新功能版本(16.0.x, 16.1.x, 16.2.x,… 16.9.x),但它不會強逼大家更新,對於過去一段時間的功能版本,也會推出安全性更新(前述的x會不斷修正問題)。 這是一個很負責任的發佈模式,不過對於開發者來講就一定很地獄。因為16.0.x的安全更新並不能無痛地整合到16.9.x中,可能每個版本重新人工修改還要來得穩健。 建議 各個分支人工修改可能更適合。最後就是取決於商業政策的考量,到底公司願意為已發佈的功能版本提供多久的支援。就以gitlab為例,其實它也只承諾維持兩三個月前的功能版本。是否會backport到多個月之前的版本,就看問題的嚴重性和backport難易度。 也分享一些筆者朋友的經驗,他們開發的是軟件跟硬件整理的軟件庫。但因為硬件有限制,例如庫的大小、算力的差異,所以最後分支多到爆炸。這也是軟硬整合的痛,問題暫時無解。除非老闆肯放棄市場。

星穹鐵道:中後期無課心得

手機‧電玩
MacauYeah・2024-02-08

分享前先講講為何會回鍋。因為筆者平常支持的RPG品牌Square Enix 實在不濟,每次更新完手機,它家的買斷型遊戲都攔淺。實在玩不下去,還是要回到米哈遊,星穹有中文、持續更新、自動存檔,從內容到技術上都比買斷型遊戲更適合手機遊玩。所以筆者就繼續來養成看看吧。 角色取得策略 之前筆者在其他文章內有提及過,免費課金制最大的痛點就是可取得的資源有上限,所以到了中後期,資源投資在什麼角色上是一個很重要的考量。但由於本文的主題是無課心得,所以筆者亦限定自己只使用免費卷或免費石抽4星角色。筆者的抽角色策略也很保守,各位應該可以很輕易地重複到。最簡單地講,只有弱點擊破效率不足時、打不過的主線時,才會考慮抽角色。 青雀 - 量子屬性 - 智識命途 主線第二章,豐饒玄鹿,弱點屬性為火、冰、量子。主線預設只有一火(主角)一冰(三月七)的組合,筆者實在打不過豐饒玄鹿。此時有兩個選擇,要麼就多抽一個量子角色,豐富一下隊中角色;要麼去打支線模擬宇宙,取得另一隻冰免費角色-黑塔。 為長遠發展,筆者先抽角色,不過運氣不怎樣,只抽到青雀。智識命途主打群體傷害,但她沒有持續傷害加成,而且戰技有運氣成份,所以強度不高。但對於主線玄鹿至少可以一戰,有抽到朋友可以隨便升一升等級就可以。 希露瓦 - 雷屬性 - 智識命途 在中期開始,除了經普通遇敵獲取【行跡素材】之外,攻略支線【模擬宇宙】也是取得【行跡素材】的重要方法。此時希露瓦配搭虛無命途的【懷疑】debuff效果可以在【模擬宇宙】達到多重疊加傷害。有條件疊加傷害的另一個四星角色應該是素裳。筆者有抽到,但因為物理屬性重疊,所以沒有練。 另外,在正常情況下,在攻略完第一章後,預設會有一火(主角)一冰(三月七)一奶(娜塔莎),再加上希露瓦,【均衡試練伍】可以穩過。通過後,可以特破角色等級上限至80,是1.6版本的封頂等級。(2.0版本才剛更新,但應該沒有調整封頂等級)

龐大的Docker Logs該如何處理? | 傳統的syslog幫到你

科技新知
MacauYeah・2024-02-02

平常大家在做單機app時,寫log有很多選擇,最簡單就是寫在檔案中。但在docker container裏面,寫檔案時要注意怎樣保留log檔,避免因為重建container時不見了。 docker 大部份官方預設image,都把log導向至stdout和stderr。這是方便docker做管理,也方便大家使用統一的docker logs指令來查看,即使到了Swarm mode底下,docker service logs也是同樣原理,使用差異不大,頂多就是不保證log的實時性。 如果網路延遲不計較的話,最大問題也是logs怎樣保存的做法。預設就是container刪走的時候,logs也會一借走。單機模式下,沿用最普遍的方法寫log的做法不是不可行,只是考慮到在極端情況下,同一個node(節點)中,有可能同時運作同一個service(服務)的多個分身(replica),這裏它們寫檔案時就有機會互相搶佔。 筆者認為,比較合理的是外部提供的服務,例如syslog,把寫檔的操作交給節點的Host OS處理。然後就保證好每筆log都會是一條完整的記錄。 以下就以linux Host裏面的syslog,為大家簡介一下設定的步驟。 設定docker 導向 syslog 把該主機的docker daemon (/etc/docker/daemon.json),設定使用syslog driver,並以特定的方式編寫syslog tag。 { "log-driver": "syslog", "log-opts": { "tag": "dockercontainer/{{.ImageName}}/{{.Name}}/{{.ID}}" } } 無腦設定已完成,重啟docker就可以了。 但為了日後管理方便,能把docker log放進獨立的一個檔案中,會更易找問題。所以我們可以進一步設定syslog。我們以Ubuntu 22.04為例,可以在/etc/rsyslog.d/下增加一個設定檔(/etc/rsyslog.d/*.conf),指定看到syslog tag以dockercontainer為首的記錄,都要獨立抽出來。 # file: /etc/rsyslog.d/51-docker.conf :syslogtag,startswith,"dockercontainer" -/var/log/dockercontainer.log 為免有檔案權限問題,手動指定檔案的所有權後,才正式重啟syslog。然後所有相關記錄都會寫在/var/log/dockercontainer.log 滾滾滾滾滾動的log檔 檔案一天一天地長大,如果可以,還是自動清掉太舊的記錄為妙。Linux Syslog,通常也會配著logrotate使用。 筆者亦以Ubuntu 22.04為例子,做了個最簡單的自動滾Log功能。目標就是當log檔案大於1M後,就要重開log檔。舊的log檔最多保留7份,多了就刪掉最舊的。 # file: /etc/logrotate.d/rsyslog-dockercontainer /var/log/dockercontainer.log { rotate 7 size 1M missingok notifempty compress delaycompress sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript } 加了設定後,什麼都不用重啟,因為它是Ubuntu 的排程動作,到執行時就會以最新的設定檔執行,詳見/etc/cron.daily/logrotate. 有需要手動測試的話,需要手動呼叫/usr/sbin/logrotate。加入-d參數後,會被視為debug mode,這是官方的說法,但因為debug mode沒有執行效果,更加像是linux中常見的dry run mode。

Steam Deck 也可以作為文字創作

科技新知
MacauYeah・2024-01-23

之前筆者就介紹了,如何使用Steam Deck作為程式開發機使用。這可能對於一般讀者來講不太常用,更常用的是做一些文書處理。筆者最近也拿著Steam Deck,也一步步地補充文書處理所缺少的軟件,正式踏入Steam Deck日常之路。 如果你沒有對系統做過任何更改,在桌面模式中,只要打開「Discover」,輸入後逐的軟件的唯一package name,就可以找到相關軟件。 但如果你像筆者之前一樣,加了homebrew等第三方系統,可能所有軟件都需要在terminal中,經過指令sudo flatpak install PACKAGE_NAME。 Chrome 唯一碼: com.google.Chrome 系統預設瀏覽器只有Firefox,不習慣的話可以另外下載Chrome。有了Chrome,至少所有的雲端文書軟件都可以用,想用Google Doc也沒有問題。 中文輸入法:Fcitx5 + Rime 唯一碼:org.fcitx.Fcitx5 唯一碼:org.fcitx.Fcitx5.Addon.Rime Steam Deck原本有自帶的輸入法,但只適用於螢幕虛擬鍵盤使用(即使用Steam key + X,打開虛擬鍵盤),而實體鍵盤就無法轉輸入法了。這時就需要Linux上的Fcitx5和Rime了。安裝很簡單,之後還要設定一下。 首次安裝後,在啟動器(桌面左下角)搜㝷及啟動 fcitx5,然後在右下角就會見到有個新的鍵盤圖示出現。 按鍵盤圖示,滑鼠右鍵,點選configure,把Rime 加入Fcitx裏面,然後Apply → Close 然後按鍵盤圖示,滑鼠左鍵,應該就會切會成中文輸入法了。這時原本的鍵盤圖示會變成中文輸入法的圖示(或者你經Ctrl-Space也可以) 最後對著中文輸入法圖示,再滑鼠右鍵,可以選擇不同的中文輸入法,例如拼音、注意、倉頡等。 有了輸入法,有了瀏覽器,世界已經都是你的了。 下載器 JDownloader 唯一碼:org.jdownloader.JDownloader 它可以用來下載大部份隱藏文件,例如YouTube video / audio 。但需要注要,首次下載JDownloader 後,還要經過軟件內部更新,否則不能使用。(就像很多手遊,下了主程式後還要下更新檔) 其他 如果你不是長期有網絡,還需要真離線版文書處理器,還可以看看LibreOffice,WPS Office。但這些都不能保證跟windows office 百分百轉換,可能還是使用雲版的Microsoft office 365還要實際。

街霸六-如何不要被【贏】成為競技遊戲的唯一目標?

手機‧電玩
MacauYeah・2024-01-19

眾所週知,玩遊戲普遍都是圖開心。很多朋友玩遊玩競技遊戲時,【贏】都是一個很重要的樂趣指標,但競技總不可能每個人都贏,輸的人反而是大多數。所以競技遊戲若沒有其他樂趣,玩著玩著,就會越來越少參與者。 問題是,競技遊戲真的有其他方面的樂趣嗎? 筆者認為是有的,但至少參與者的心態要放開。 就像求學不是求分數一樣,探索一門新知識比分高低要來得重要,玩遊戲也更是如此。以筆者玩街霸六的情況來講,可以探索的地方實在很多:- 目押、取消連技- 對空- 對策動力衝擊- 對策突進- 狗昇、防狗昇- 打亂動、搶制(Abare)- 壓起身 (Meaty)- 安全跳 (Safe Jump)- 立回 (Neutral)- 確反 (Punish)- 差合 (Whiff Punish)- 打拆 (Shimmy) 最後才引伸不同的角色對策。 而大部份人都一定會陷入的低潮就是:當等級越高,對手的熟練度就越高,對機制的理解就越深,然後就會對戰得越沮喪。筆者因為一些原由,看到別人都爬分時都有非常沮喪的練歷,也看到退遊戲的心路歷程分享。 筆者屬低分區,無條件指導別人如何進步,但筆者可以提的意見是,要逆向思維:自己會輸,是因為對方是強者,跟強者對戰,其實是在學習、在感受。有時候,筆者也會因些微差距而輸了對局。有時候,筆者也會想,是不是對方運氣好。 但感謝街霸六的對戰大堂,只要對方願意,可以很方便的跟同一位對手重複對戰。經過重複對戰,你就會知道是不是真的只是對方運氣好。更重要的是,重複對戰可以有助於大家熟知對手的策略,只要有對策,對局就不一樣。就算當下無解,也可以在訓練室再進一步研究。 街霸六的對戰機制和訓練室的各項細微功能,是眾多手遊、什至是主機遊戲,都無法提供的。可以隨時與陌生對手匹配友誼賽,可以自定義對戰,可以重播比賽,觀看對手的輸入按鍵,訓練室還可以查幀表,錄動作,混合抽樣播放動作,讓你可以有目的性地實驗、練習反應對策。 在分數線機制上也有一些保障,不同角色分數獨立,打上特別段位後有一次跌級保障。讓大家在排名賽上,輸掉也不至於十分心痛。若果心理上實在受不住排名賽的壓力,友誼賽絕對低分爬上高分區的一個試招的好選擇。在對戰大堂的友誼賽中,很易會遇到比自己排名高的對手,多找對方實戰看看,輸了沒有成本,但贏得了經驗。

Spring Boot 01 - 萬物始於Spring boot context

科技新知
MacauYeah・2024-01-16

Spring Boot 01 - 萬物始於Spring boot context 筆者早些時候向一位朋友討論,為何Java那麼不受歡迎。朋友一句就回答,Java煩爆,沒有人會喜歡。 老實講,Java在句法上,實在囉唆。但以筆者的經驗,即使使用其他語言和開發框架,在實戰到一定複雜程度下,其實也一樣煩爆。 而現在的Java框架中,就以Spring boot的入門門檻低。筆者從Spring boot 1.x用到現在的3.x,也真的感受到更多的簡化,所以筆者也加入一起推廣Spring boot的行列。筆者將會通過一系列最小的可執行程式,為大家講解Spring在Web和資料庫上的應用。 所以現在就不廢話,馬上開壇作法 快速下戴模版 使用Spring initializr,可以很容易就建立一個以Spring boot starter為底的java project。大家可以使用Spring 官網又或是vscode plugin 快速地建立一個maven或gradle project。筆者較為熟悉maven,就以maven起一個範例。 在使用Spring initializr有幾件事必需要指定的: Spring boot version: 3.x.y 或以上 Language: java Group Id: 請選擇有意思的域名,如果你用github,可以選 io.github.yourusername artifactId: 這個範例的名字,例如commandline Packaging type: 本次使用jar,日後若開發web 應用,可以使用war Java version: 17或以上 之後就不用選了。若你經官網起範例,你會得到一個zip檔,下載後解壓縮。若你使用vscode插件,最後插件會叫有一個位置儲存。它們都是最後也是會得到同一樣範例Java project。 你使用Vscode,Intellij打開,IDE都會自動辨識到它是java maven project,同時會顯示java和maven結構。道理上你用Intellij 應該可以無腦開始編譯(Community 或Ultimate版都可以), Vscode有安裝Extension Pack for Java也會開始自動編譯。不想麻煩,也可以試用Github Codespaces - java。Github Codespaces其實就是一個雲上的vscode,經網頁可以連到Github VM內的vscode,所以它也會有齊Extension Pack for Java等插件。 筆者最後也會上載已完成的範例,它也可以在Github Codespaces上以Java執行或繼續開發。 打開project中的pom.xml,它為我們添加了兩個很重要的lib org.springframework.boot spring-boot-starter ... ... org.springframework.boot spring-boot-maven-plugin spring-boot-starter是重中之重,它定義了怎樣動態地設定日後的其他lib,它是讓我們可以無腦設定的一個關鍵。(但若大家有很多客制化的設定,就要返撲歸真地逐個lib叫起)。 maven在預設情況下,只會負責編譯和打包目前的project原始碼。所有相關依賴(就是xml中的dependency),並不會自動包起。而spring-boot-maven-plugin,就是幫我們把相關依據都包在一起,讓你的jar可以獨立行起來。 註: 若大家在開發lib jar,並不是一個獨立執行的jar,也就是原始碼上沒有main函數,大家就不應該引用spring-boot-starter和spring-boot-maven-plugin。 我們繼續看其他原始碼,整個資料夾就像以下那樣。 . |-- HELP.md |-- pom.xml `-- src |-- main | |-- java | | `-- io | | `-- github | | `-- macauyeah | | `-- springboot | | `-- tutorial | | `-- commandline | | `-- CommandlineApplication.java | `-- resources | `-- application.properties `-- test `-- java `-- io `-- github `-- macauyeah `-- springboot `-- tutorial `-- commandline `-- CommandlineApplicationTests.java CommandlineApplication是我們有main函數的java class。我像可以經過IDE運行main又或者下指令mvn spring-boot:run來執行。 正式開始我們的Commandline開發 我們在CommandlineApplication.class中,加入新的程式碼,實現ApplicationRunner和它的函數run。 package io.github.macauyeah.springboot.tutorial.commandline; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; // other import @SpringBootApplication public class CommandlineApplication implements ApplicationRunner { static Logger LOG = LoggerFactory.getLogger(CommandlineApplication.class); public static void main(String[] args) { SpringApplication.run(CommandlineApplication.class, args); } @Override public void run(ApplicationArguments args) throws Exception { args.getOptionNames().stream().forEach(optionName -> { LOG.debug("option name:" + optionName); args.getOptionValues(optionName).forEach(optionValue -> { LOG.debug("option values:" + optionValue); }); }); LOG.debug("program end."); } // ... 這個run函數很直白,就是更好地演譯main中的String[] args。 但大家還要看清楚,這個main並沒有直接執行run。其實它是靠SpringApplication.run及@SpringBootApplication,跑一堆自動設定,最後因為傳入CommandlineApplication.class是一個Spring 可以處理的ApplicationRunner,所以才呼叫它的CommandlineApplication.run。 換個講法,如果今天做的是web應用,傳入去的就會是SpringBootServletInitializer,這個SpringBootServletInitializer也不一定跟main是同一個class。 如果大家有興趣,可以經過反編譯器,點入@SpringBootApplication看它的原始碼,你就可以看到它其實代表了很多自動化的東西。如果我們只做一些在同一個模組下生效的事情,《自動化》極大地降低了大家入門門檻。一般來講,如果大家不在意程式碼的複用度,比較少機會自行設定,自動化已經很有用。而隨著系統規模增加,多模組就慢慢地顯得重要,在大家了解完基本的Spring後,著者再從測試用途test case入手,為大家介紹如何手動設定。 Source Code Commandline Application

Spring Boot - Maven Cheat sheet

科技新知
MacauYeah・2024-01-12

基礎 刪除所有結果,全部重新編譯 mvn clean compile 跑起用Spring boot寫的main class,運行Spring boot context。 mvn spring-boot:run # or mvn clean compile spring-boot:run 執行測試用例,預設只會測試test資料夾下以某些命名規則的class(例如class名以Tests或Test結尾的class,其他命名規則筆者未有能力一一驗證) mvn test # or mvn clean compile test 多Profile、多組件、多測試 使用-P指定編譯時的選用pom.xml中的project.profiles.profile參數。也可以用此來傳遞到spring profile,使得編譯後的spring war預設選擇特定profile。 mvn clean compile -PmvnProfile # or mvn clean compile spring-boot:run -PmvnProfile 使用-pl限定mvn指令只對某個子組件生效,但有時候子組件之間也有引用關係,所以需要再額外加上-am參數(--also-make) mvn clean compile spring-boot:run -pl SUBMODULE_NAME -am 使用-Dtest=限定只執行某個class的測試用例,或單個測試函數。(可以無視class名的命名規則) mvn test -Dtest=TEST_CLASS_NAME # or mvn test -Dtest=TEST_CLASS_NAME#TES_METHOD_NAME 若屬於多組件情況下,其他子模組找不到同樣名稱的測試,會測試失敗。需要再加上-Dsurefire.failIfNoSpecifiedTests=false mvn test -pl SUBMODULE_NAME -am -Dtest=TEST_CLASS_NAME -Dsurefire.failIfNoSpecifiedTests=false # or mvn test -pl SUBMODULE_NAME -am -Dtest=TEST_CLASS_NAME#TES_METHOD_NAME -Dsurefire.failIfNoSpecifiedTests=false 打包 在本機電腦中,把java變成jar或者war。通常用於自行發佈的環境中。 mvn package 有時特定Profile沒法成功執行測試用例,或者你認為有些測試問題不影響使用,需要跳過package中的test。 mvn package -Dmaven.test.skip=true # won't compile test folder mvn package -DskipTests=true # compile, but won't run 例外情況 強行把一個第三方jar,種到本機電腦中的.m2/repository # copy from https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html mvn install:install-file -Dfile= -DgroupId= -DartifactId= -Dversio

街霸六的元宇宙大笪地對戰大廳

手機‧電玩
MacauYeah・2023-12-26

上期就為大家介紹了Modern Mode的新系統。今期就再繼續為大家介紹新的對戰系統。(上期連結: https://lifemag.cyberctm.com/zh_TW/blog/macauyeah/13954 ) 找個陪練很重要 現在街霸五中,網上對戰不外乎是隨機的排名賽、隨機的友誼賽、邀請特定網友在對戰大廳輪流對賽。看下去沒有什麼大問題對不對? 實質上就是一切都很隨機,而對戰大廳很少人懂得運用。 街霸六中一個很重要的改動,就是在隨機的排名賽和友誼賽,加入賽後自訂賽制的玩法。排名賽上遇到五五波的對手,想跟它再打幾場? 可以,馬上進入自訂友誼賽,打個夠。這個改動很必要,在過去的日子裏,特發跟不同人隨便打兩三場,根本不知道應對手段;跟同一個對手來回對策,才會慢慢知道輸在哪裏,有沒有什麼地方是博奕的盲點。猜包剪揼連輸三場,你覺得是對手運氣上壓制你,但連猜十場你也輸,就代表你真的被對方看透。若在排名賽上沒有碰到想賽後重複對戰的對手,遊戲商亦很佛心地重現了一個類似大笪地的對戰大廳,讓你可以在元宇宙坐在一個虛疑街機框下,等待那些跟你一樣不太介意分數,等級差不多、但只想連續思考對策的朋友。 在過去街霸五中,隨機的友誼賽和對戰大廳,對筆者這些低端玩家來說實在沒有什麼用途。友誼賽實力差距很大,基本上就是老手開發新帳號來碾壓新手的地方。對戰大廳則是連線品質參差問題,見到高分的不敢進去,低分的基本上網路卡到不能玩。當時最能遇到熟練度差不多的對手,就只有排名戰,但同一名對手的排名戰機會不多,然後大家又非常在意分數的上上落落,所以當時的對戰實在稱不上快樂。 對比這個情況,街霸六就變得放鬆很多,大家更容易地在大笪地中找到差不多的對手陪練,不用計較分數。大笪地的成功,並不是單純地因為可以自定義對戰,它的連線品質提高,也是穩定在線玩家數量的一大原因。 其他重要改進 單從字文上,或許你覺得整個街霸六都是換湯不換藥。但筆者很負責任的說,它是在硬技術和設計上,都做到很大的改進。雖然不能稱為劃時代的改進,但有了它們,遊戲更友善: 對戰系統可以全平台跨平台對戰,PS、XBox、PC可以大混戰。你能匹配到的有效在線玩家變多了。 提高連線品質,現在那怕是Steam Deck連上Wifi也能網上進行對戰,大家也不那麼懼怕延遲的問題。 大笪地加入社交元素,你還可以通過故事模式,解鎖自定義格鬥技,在非正式的對戰中跟別人惡攪對戰。 練習模式加入極重要的幀數顯示,大家更有條件地自定義練習情境。 玩家們已經極少再需要上網查幀數資料,除了無敵幀需要上網查以外,其他的自行試就好。 官方在練習模式中預錄制了一些情境練習,例如對空、破防、解投等,讓大家可以直接練。但在解投的情境中,更讓筆者明白這遊戲有多麼的爾虞我詐。 這兩期講的東西,都是Capcom針對核心遊戲元素的多項精進。吸收了街霸五的技術和策略上的失敗,街霸六就從軟硬兩方向大改進。Modern Mode在直正意義上可以讓新手入門,但又不致於無腦遊戲。對戰機制,可以讓大家不只關注排名賽,更大地去提供實戰環境讓大家實驗自己的PvP策略。

格鬥新老手也很友好的街霸六 | MORDEN MODE

手機‧電玩
MacauYeah・2023-12-22

街霸六已經出了半年有多,但筆者也是近期在購買steam deck 後才加入街霸六。一玩就實在愛不惜手,特別是steam deck的加持,讓筆者可以在午休時間大方地玩。 可能好多網媒都有介紹它,亦十分讚賞它的單機故事模式。但對於沒有時間筆者來說,慢慢跟故事拜師成長,解鎖不用招式,實在讓筆者耐不下心。而真正讓筆者感到友好的,是它的操作系統和對戰系統,讓它可以達到老手有老手的開心,新人有新人的快樂。今期,就升為大家介紹它新的操作系統。 MORDEN MODE 經常有人誤會,格鬥遊戲玩的是連招,如果人人都可以自動連招,根本就是小朋友遊戲,拿不上大台,也不會有舉辦比賽的價值。所以有一些人,會看少「任天堂明星大亂鬥」的價值,因為不論多新手,都可以打出基本combo。但說實在,它是街霸6出來以前,最有條件同時允許新老手同樂的遊戲。 格鬥遊戲,什至其他競技遊戲,對於同等操作熟練度的選手來說,他們的比拼是應對策略。而相對公平的競技遊戲,應對策略就是很像是博弈,沒有100%安全的招,就像包剪揼一樣,可以有特定的對應策略。格鬥遊戲與包剪揼最大的差異,是在足夠熟練和專注的情況下,雙方是有條件作出對策的,所以格鬥遊戲不完全是盲猜。而過去最大的問題,就是格鬥遊戲太難讓新手學會博奕,外人看去就是combo為王,搓招難,就放棄吧。 街霸五在容納新手方面,其實都下過很多努力,包括減少每個角色招式數量,較寬鬆的combo 輸入時間,提供可錄影、重播、幀數檢視的練習模式。可惜搓招門檻始終也是讓很外行人放棄的原因。而街霸六,則提出一個很多人都提過的做法,但沒有廠商真的成功過的做法,那就是一鍵搓招與傳統搓招共存的做法。 玩家可以在對戰前,選擇新的【Modern Mode】(現代模式),然後享受以下功能便利。 簡易使出必殺技。通過 單一方向鍵+SP鍵使出不同的【必殺技】 單一方向鍵+SP+AUTO鍵使出不同的【OD必殺技】 單一方向鍵+SP+重攻擊鍵使出不同的【超必殺技】 攻擊力比較搓招或【Classic Mode】有下調 簡單使出連招。通過 不同的單一攻擊鍵+AUTO鍵 連打 使出三套特定的連技 攻擊力比較搓招或【Classic Mode】有下調 若要使用【輕、中、重必殺技】,仍需要使用傳統的搓招方式。 攻擊力回到100%。 對比【Classic Mode】,【Modern Mode】有些拳腳攻擊、必殺技的差異化版本無法使用。 例如Luke在MORDEN MODE中只可以使出後重拳,沒有後重腳。 例如Ryun在MORDEN MODE中只可以使出中旋風腿,沒有輕、重版本。 但依然可以打出大部份的搓招 + 連技。 當然,玩家可以選擇【Classic Mode】(傳統模式),一切按鍵都跟過去一樣,有輕、中、重之分。 筆者最欣賞的,就是這個【Modern Mode】的出現。因為它可以降底學習成功,但又不失公平性,讓新、老朋友可以打出一場有博弈味道的友誼賽。例如正面跳入攻擊,在過去的高端對局中,只能作為突襲的戰術,不能隨便跳。但在低端對局,正面跳入攻擊就經常是老手欺負新手的一個有效途徑。新手想要對策正面跳入,必需經過一個搓招,才能使用昇龍拳來穩定對空。但在【Modern Mode】,簡單一鍵昇龍,就可以代解威脅,雖然攻擊力變底,但正面跳入不能當是賴招使用,讓大家回到思考何時跳入的博弈問題中。 如果說【Modern Mode】只為新手當做過渡期而使用的模式,那就真的小看了它的設定。在遊戲正式推出後,意外地出現高端對局中使用【Modern Mode】,因為它可以提供快更的反應速度,可以彌補一些角色上的短處。 對筆者來講,【Modern Mode】最重要的並不是簡易必殺技。因為追求傷害量的情況下,搓招很必要的。筆者看上它的原因是它能有效地簡化Drive Rush的輸入,令到筆者可以更易地通過【延長攻擊手段】最得反應的時間。一般讀者可能不明白進攻方為何要反應,不是防守方才要做反應嗎? 在格鬥類遊戲中,大部份時間防守就是死按一個【後】或【下後】鍵就足夠,在街霸六當中,更因為有Over Drive、Drive Impact等系統,防守方有更多博奕下的對策方案。怎樣打穿敵人的防守,是進攻方要用腦的事,更因為如此,有些人選擇打後手,等對方出錯,反而很有利。 但進攻才是格鬥遊戲的重點,要走向高分層次,就必需要跨越【Hit Confirm】的障礙。經過【Hit Confirm】,若然連招中途就發現打不中對手,就以一個更安全的攻擊收尾;若然打中了,做使用更多資源打出更高傷害。提高自己【Hit Confirm】的反應能力,基本就是跟年齡作對。所以筆者就需要經過其他手段,例如:Drive Rush來延長自己的攻擊節奏,好讓反應不來的筆者有更多時間選擇打安全招還是全力攻擊。 下期,筆者會再聊一聊對戰機制的改進

找一個可以私有化的協作平台

科技新知
MacauYeah・2023-12-19

在現今這個網路為王的年代,大部份文書等編輯工作都可以在Google Drive, One Drive那邊多人協作。唯一的問題是,你是否考慮資料保密問題。 一些開放資料,放在雲端上,故然無問題;個人用資料,就自己為自己負上保密責任。但作為一家公司,把自家客戶的資料放在Google Drive、One Drive上,你又會否覺得足夠保密? 不放在這些協作平台上,改為自購一個NAS File Server,把共享檔案都放進去,這樣又足夠方便嗎?現在File Server最大的問題,是無法提供同時協作編輯的功能,想在同一個檔案,多人同時更新不同的部份,是不可能的。 Etherpad-lite 如果大家只需要一起寫文字稿,可以試用Etherpad-lite https://github.com/ether/etherpad-lite 。 筆者試用過,它提供實時協作,其他人的更改可以即時顯示,也有一些基本的排版功能。缺點是lite版沒有好好處理大量的資料問題,一次過複制貼上大量文稿的話,會出現網路問題。 NOCODB 如果大家需要的是試算表,可以試用NOCODB https://github.com/nocodb/nocodb 。它強大的地方,是可以匯入CSV, Excel,做欄位搜尋。老實講,這些功能,對於一個IT人來說,隨便安裝一個資料庫,例如:MySQL、 MSSQL, 都可以做到匯入結構性資料,並供多人操作資料。但對於普通用戶來講,要學會操作SQL語言,實在有難度。而經過nocodb之後,可以把MySQL等轉化為常見的試算表型式,實在驚喜。而且,它也能提供一些簡單的填表方式(Google Form)

Switch / Steam Deck / Mobile 使用體驗大比拼 (三)

手機‧電玩
MacauYeah・2023-12-14

上兩期,筆者從機身重量、續航性兩方面,對於遊戲機身便攜性的影響,今期最後一期,就從穩定性方面去討論,最後再做一個綜合影響。 沒有對比也就沒有傷害 - Mobile - Smart Phone 筆者所講的穩定性,其實就是正常運行一個遊戲,不會出現閃退的情況,讓你可以正正常常玩完一款遊戲。但因為Mobile原本是多用途機器,你玩著玩著,可以就要跳出遊戲回覆信息,但再次回到遊戲後,能不能正常運行的不知道。 大部份iOS遊戲,因為舊iphone機能限制,基本上跳出去後,都因為不夠RAM,回來後遊戲會重置。除非你打死不切換,否則一款遊戲沒有頻繁auto save功能,根本玩不下去。Android可能會好一點,有不同機型可以選擇,多一點RAM總是安全一點。 強行地用Linux運行Windows的黑科技 - Steam Deck 老實說,Windows已經不夠穩定,用Linux運行Windows Game,會比較穩定嗎?不過最幸運的是,Steam Deck有技術支援,更有社群支援,各遊戲經過Steam官方驗證,連續遊玩下閃退情況都很少。不穩定的原因,反而是Steam Deck主機本身。 在筆者遊玩的經驗中,待機後再打開,有一定機會率會整個遊戲閃退。這些問題在遊玩大作,特別是3A大作,會引來一個很不愉快的體驗。因為它們的auto save位置點一般都是以情節點來做考量,而以上班族來講,三步一待機的使用情境也很常見,那麼觸發閃退的機會率就很高。某次啟動會隨機引起閃退遊戲,真的欲哭無淚。 筆者也翻查過網上的資料,一年多前就有這個問題存在,而官方亦無法根治。筆者在寫稿的途中,還在測試坊間一些可能的補救方式,但因為時間不長,不敢說這問題是可以解決的。 穩定發揮 - Switch Switch在穩定性真的無可挑剔,多次待機後都沒有太多問題。完全貼合它的市場定位:在家可以隨時在電視玩,出外也可以四處走。隨時隨地停,隨時隨地再開。最多最多都是遊玩實體卡帶時,因為接觸不良而閃退。但這些不可避免的,因為實體卡始終是物理型態存在,跟著Switch四處奔波,難免會出問題。但下載數位版,存放於SD卡就不會有閃退。至少SD卡不會像實體卡會經常替換,所以出問題的機會也較少。 綜合體驗 其實討論了幾個方面,筆者都從是省心遊玩的角度出發去討論。 Mobile在裝備上會最少煩惱,想最輕鬆出問,這個是不二選擇,但考慮玩非課金類遊戲就最沒有保障。 Steam Deck優點是移動堡壘,若你玩的是高性能需求的遊戲,你只能選它。但想隨時玩就未必做得到。 Switch 在重量和穩定性上面最有優勢,考量延續性體驗,這個是首選。

Switch / Steam Deck / Mobile 使用體驗大比拼 (二)

手機‧電玩
MacauYeah・2023-12-12

上期,筆者為大家簡介機身重量對於遊戲機身便攜性的影響,今期,繼續從續航性方面去討論對於便攜性的影響。 依然是王者 - Mobile - Smart Phone 就如同重量一樣,續航性的理論值,依然是Mobile最優勝。單看電池容量,其實無能說手機最優,就算現在的iphone15,電池容量其實也比Switch, Steam Deck要低。能比得上的,可能只有iphone 15 Pro。但若果連同充電的方便性,Mobile是最易邊玩邊充的。一般來講,如果不以全效能去運行遊戲,Mobile是的電量是相當安心的。 但也如同重量一樣,續航性理論值,是Mobile最好,但不是安心長期遊玩的媒介。 一來,Mobile,一般都是用作社交通訊用,它的電量是分享給一整天使用的。一不小心遊戲時間長了,那天晚上可能就沒有電話用。除非大家想隨身攜帶奶媽(充電寶),但這是用重量來換取遊戲時間。所以筆者不會把它當作首選。 巨無霸 - Steam Deck 空有其名的巨無霸。在電池容量上,它是三者中最大的一款,但因為它對照的遊戲效能,是PS4/5、XBox One/X/S、PC等的大作上面。那些主機大作,對電量是極其大需求的,單憑散熱風篇的聲音,你就知道不秒。一般遊戲的預設畫面品質,就只夠1-2小時的遊戲。實在想延長,就必需要下調Frame Rate或是畫面品質。 玩消耗戰必選的設備 - Switch Switch預設電量不多,但因為畫面其實也不能要求太多,所以它的續航性不低。相比Mobile,Switch就是完完全全的純遊玩設備,也不需要筆者去刻意規劃電量。沒電?關機就好。待機也是單純的待機,不需要什麼定期連上Wifi、GPS,藍牙亦單純地為耳機及手柄使用。想更省電,就待機前就全數關掉就好。 綜合體驗 老實說,看完重量及續航性之後,Steam Deck主打市場明顯不是遊戲掌機,而是一台可以搬走的PC。你可以方便地整台電腦帶走,從自己家到公司,從公司去親友家。它的體型,比主機和Notebook要細,它的售價,也比一台Notebook要便宜。但想拿著玩?可能不會特別開心。 Mobile在重量及續航性綜合考量,其實很有競爭力。不過考量用途問題,否則你也很難安心用Mobile來玩遊戲。 老任的Switch,重量及續航性在初推出市場之際,筆者都不看好。但實用和對比之後,畫面效能和續航性控制得還不錯。

Lambda 表達式之可讀性

科技新知
MacauYeah・2023-11-24

Java作為一個真OOP物件導向的程式,在設計和編寫上是很嚴謹,什至是囉嗦的程度。近年很多Programmer因為各種原因,都放棄Java跳船去其他語言。 Javascript是其中一個很多人的選擇,因為Javascript有nodejs的加持,在Web世界下,可以同時走frontend、backend路線。而Javacript亦有一個很明顯的特性,就是大部份的library都以callback的型式出現。另外,Javascript也讓很多人覺得很簡潔,這除了是因為它沒有強型態的規限外,另一個原因也是因為有callback的大量使用。 Function Pointer 其實callback,籠統一點講就是在一個function A傳入另一個function pointer B。而編寫function A的作者,並初期並不知道function pointer B的實際操作會是什麼。A作者只是強調在特別定時候,它就會使用這個function pointer B。而這種把function pointer 傳來傳去的做法,就可以看成是Functional Programming的基礎。 Functional Programming除了把function pointer 當成是一等公民以外,還有很多附加要求,例如: Pure Function: 它只會使用到自己的Local Variable本地變數,這樣它的作用域就鎖死在Function內部,就不會有副作用。 傳統的OOP,Class中不少變數會以Class Attribute型式存在,雖然它們可能是private attribute,但還是獨立於Function外,這樣各Function的操作,都要靠作者好好地記著Class Attribute的狀態。 Nested Functions: 與普通程式語言類似,很多情況下都需要local variable,而Function Programming要足夠好用的話,就需要彈性地在function裏定義local function pointer。 Java Lambda 表達式 其實從Java 8開始,就有提供Lambda表達式,這是一個可以制作匿名function pointer的方法。所以硬要講,Java也可以做Functional Programming。 但必需要盡早強調的是,Java經常性地使用class attribute,它們很多時候都會引申請狀態的概念。即是在它們必需經過特定步驟後,class attribute才會有特定的意義。也就是Lambda表達式想保持Pure Function的特性,它可以使用的時期就有很大限制。 但我們還有必要使用Lambda嗎? 以筆者的經驗來講,它還是有作用的,特別在於它可以改善Class Function的閱讀性。 例如下面一個Java Class。它是一個工廠,提供一個服務可以生產一堆車。那些車而需要經過特定檢測,才能推出。 public class Factory { // ex1 public static List generateListOfCarByForLoop() { List tempCars = new ArrayList(); // many other logic // many other logic // many other logic List passTestCars = new ArrayList(); for (Car car : tempCars) { if (car.getWheels().size() == 4) { // many other check logics // many other check logics // many other check logics passTestCars.add(car); } } return passTestCars; } } 中間的for loop可以用lambda來改寫。 // ex2 public static List generateListOfCarByLamda() { List cars = new ArrayList(); // many other logic // many other logic // many other logic cars = cars.stream().filter((car) -> { if (car.getWheels().size() == 4) { // many other check logics // many other check logics // many other check logics return true; } return false; }).toList(); return cars; } 有人會說,上述ex2只是形式上改變了,沒有特別易讀。就像ex3這樣,把特定邏輯抽成獨立function,才是真正的易讀,對嗎? // ex3 public static List generateListOfCarByForLoopFunction() { List tempCars = new ArrayList(); // many other logic // many other logic // many other logic List passTestCars = filterCarsByWheelsSize(tempCars, 4); return passTestCars; } private static List filterCarsByWheelsSize(List originalList, int targetSize) { List passTestCars = new ArrayList(); for (Car car : originalList) { if (car.getWheels().size() == targetSize) { // many other check logics // many other check logics // many other check logics passTestCars.add(car); } } return passTestCars; } 上述ex3是一個有效的改進。如果大家不計較傳入參數的先後順序及交互影響的話,就已經很足夠。 但如果大家對於多參數的解讀又怎樣? private static List someotherfunction(List cars, List wheels) 大家又會不會突然停住,想想到底是cars影響wheels,還是wheels影響cars? 對於多參數的function來講,相互影響就會越來越多,但使用Lambda的話,可以針對性地表達這是一個Predicate Lambda。 // ex4 public static List generateListOfCarByLamdaComposition() { List cars = new ArrayList(); // many other logic // many other logic // many other logic List wheels = new ArrayList(4); cars = cars.stream().filter( filterCarByWheelSizePredicate(wheels) ).toList(); return cars; } private static Predicate filterCarByWheelSizePredicate(List wheels){ return (car) -> { if (car.getWheels().size() == wheels.size()) { // many other check logics // many other check logics // many other check logics return true; } return false; }; } 就最後的ex4版本,可以很明確的知道是cars被Predicate所作用。 如果大家還有其他使用Lambda的明顯好處,也可以一起來Github分享大家的Code