搜尋

搜尋結果

Spring Data Jpa 自動化的選擇 - Code First
科技新知
MacauYeah・2025-01-22

Code First vs Database First 在早期SQL資料庫盛行的年代,在設計要使用資料庫儲存資料時,很經常遇到一個策略選擇的問題Code First vs Database First 這兩個策略的差異可能越來越講不清,筆者也找了一些現時網路上的講法。 Code First 先從寫程式的角度出發,設計數據模型,再使用工具把你程式碼中的數據模型類Class,生成一個對應用SQL資料庫的表Table,自動編做好對應的數據結構Schema。這樣你在設計時,以程式設計為主導,方便熟悉程式的人使用。這常見於第一手開發設計,因為資料都是第一次收集和儲存,考慮收集程式的運作最為實際。 Database First 先從SQL資料庫的儲存、取用資料的方式出發,先用SQL成生Table及Schema,再轉變成為程式碼中的數據模型。這樣的資料庫在日後作分析用途時,比較簡單易懂,方便使用熟悉SQL的人去使用。這也常見於二次開發程式,因為這樣可以確保不會錯誤地破壞原有資料庫。 那麼筆者為何講這兩個差異越來越講不清?那是因為現在的資料庫不能單純地只考慮初次或二次開發問題,而是需要考慮多個系統協調運行的問題。 多系統共享協定 Database First 因為隨著資料系統發展,有些資料會作為數據源出現或用作共享媒界,如果一定要對設計策略作分類,在多系統協調運作下,這些應該叫使Database First。不論它們是SQL還是NoSQL資料庫,我們的程式碼都要為這個預先定義好的數據結構作出妥協。不論使用工具,還是人為分析,都要把共享的數據結構轉換成自己程式中的數據模型。 即使不是多系統協調運作,有時候因為要移植系統,但同時又要令兩個系統版本相容。新系統也是被逼使用Database First的方式設計。 自動化考量 Code First 前述我們講到,很多時候我們也是從Database First的方式思考。不過筆者就這個Database First,也弄到滿身傷痕。 首先,拋開工具轉換的誤差,我們人為的把共享數據轉化為數據模型,共享數據有時會有一些先天的缺陷,例如 資料沒有設計Primay Key 主鍵,唯一鍵、日期時間的定義不明確等。面對一些意義不明的數據來源,要整合確實很要命。而且二次開發中,不可能100%重用原有的資料庫結構,很多時都會加入新的欄位或更多表格去計數。一旦加入新欄位,在團隊多人開發中,那麼使用唯一的共享開發環境,就變很易有程式碼上的衝突。 若需要多人開發,各人有一個Code First的開發用資料庫,是很必要的。這也可以在系統正式升級前,對比開發中資料庫及舊資料庫的結構,觀看它們之間的差異,評估升級的風險。 也許Code First並不是重點,重點是可以隨時建立一個測試用的資料庫,這才方便合作開發。自動化的地方,不單只限於數據結構,範例資料也該是如此。如果有維繫一個初始範例資料,可以在有需要時自動生成,對於多變的環境一定有很幫助。 現時,筆者基本上都會人為檢視資料庫,人工對照編寫程式中的資料結構即是人工的Database First,並確保那時程式再次經自動化生成的測試用資料庫,並沒有失真即是Code First。至於範例資料,初期筆者也只使用SQL生成,但後期因為資料結構開始複雜,筆者也暫暫使用程式碼生成,雖然工作量會多了,但對於資料庫升級、品牌更換,這是很有效的手段,程式碼升級測試也更順暢,絕比SQL生成更易維護。 Ref Code First vs Database First httpsbuiltin.comarticlescodefirstvsdatabasefirstapproach

為程所困-是什麼讓你不想寫自動化測試?
科技新知
MacauYeah・2025-01-08

測試場 VS 自動化測試 筆者一直地更新自己過去所編寫的程式,很恐怖的是,那時的自己很少思考過怎樣寫測試Test Case。致使每次做更新時,都膽戰心驚,要手動建立測試場,人肉去測試每個可能有受影響的地方。在那些年的時候,有能力自己搭建測試場,已經是萬幸。但當面對一些要長期維護的程式,測試場的人肉測試並不是一個有效的方法,一來費時間,二來人腦記憶並不可靠。單靠自己去想想那些地方受影響,再測試,某程度是在挑戰人腦的記憶上限。如果是團隊合作,就更麻煩,你以為修改不會影響到其他人,結果卻是翻天覆地。 所以為求長治久安,編寫自動化測試,是有必要的。這些自動化測試,都算是回歸測試,每次程式有任何地方改動,都確保所有自動化測試被通過。理想始終是理想,但實際操作又會遇到怎麼的問題? 以筆者剛更新的程式為例,難以測試主要是當初沒有想過要測試這件事,所以程式結構通常是【連續順序】地執行。想分段測試?除非先重構。 Function中太多自己創建的Object 回顧自己的程式,初期編寫時,總會我手寫我心,每想要創建任何資源,在java中就會使用 new 字眼,或是自行呼叫某些 builder 類來取得資源,這是其中一個令自己無法寫測試的原因。 我們要想想,這些資源,是不是自己Function中所關心的核心。如果這個資源是被直接回傳的,我們要保留,如果它是HttpClient,只是要來獲取其他資源的媒介,我們或許可以利用依賴注入來取得它,即是把 HttpClient 改為經呼叫方傳入。注入的好處時,我們可以在Test中,修改那些資源的行為和結果。更進一步的是,把那些資源改為 interface 的方式存取,那麼在 Test 中就能更任意地控制該資源的行為。 首次重構某些資源成為依賴注入,大部份都會影響呼叫方,很多地方都要重寫。不論使用constructor injection, setter injection, annotation injection 等,上傳呼叫方,或多或少都會要加減改變參數。極致地,我們把構建都交給Program 框架去做,例如Spring Boot中,各種資源,都交給框架去自動配致。當然,這種做法的學習成本高,除錯成本也高。 【注入】其實是想在控作那些資源,在測試中運行得到固定的行為。使用前述的HttpClient例子,當我們業務邏輯是先訪問外部Web API,再根據結果做處理,那麼我們測試時,就會想模擬Web Api的結果。如果要做到自動化測試,最強硬的手段,就修改自己的HttpClient,模疑給出固定結果。 想要做到這種,在傳統的Java中,我們需要透過進一步抽離Interface去做。但這樣做很累,所以筆者通常會用如Mockito的程式庫,去修改HttpClient的行為。有興趣直接看程式碼的讀者,可以去看 github 。 當然,上述的 HttpClient 例子,使用測試場也有可做測試,自己再去模擬那些Web Api的回傳,有些情況下,這樣會更真實,但大家就必需好好定義測試場的行為。因為測試場可能與團隊的其他成員所共用,有機會其他人可能想要更多互動的測試方式,而非固定的結果。但並上非固定結果的測試場,自動化要測試的可控度就減少。

Docker 來源掃瞄 - Docker Image Scan
科技新知
MacauYeah・2024-12-19

當網安要求越來越高時,我們也要留心 docker image 的來源是不是有漏洞問題。 docker hub 本身就已經有一些安全掃瞄報告,以 nginx 的 1.27.3 版本為例, docker hub nginx 1.27.3 , docker hub 已經列出相當多的CVE漏洞。 不過對於不公開的 docker image ,安全描瞄可是要收費的。作為小團隊,可能想先尋求一些簡單的免費方案。如果你想同樣的需求,可能Trivy會幫到你。 Trivy Trivy 是一個用於描瞄軟件版本依賴或設定檔是否引用到一些有漏洞問題的軟件,它也能檢測 docker image 是否有漏洞或錯誤設定的問題。而且更好的是, Trivy 本身亦有 Docker Image 版本,我們就不用煩惱怎樣弄一個 Trivy 的執行環境,只要可以運行 docker ,有網路就可以了。但使用 Docker Image 版的 Trivy 有一個額外要求,就是它要有主機上的 docker.sock 權限。 描瞄的指令如下,其中 docker.sock 就是為了讓 containers 內部的程式可以存取主機的 docker daemon , .cache 則是為了方便暫在下載資源。 上面故意用 nginx 的兩個同版本號不同平台的 docker image,其實就是為了引出一些潛在問題。nginx 預設是使用的debain OS的,在筆者寫文章的當下,已經更新到最近的 image ,但始終有一大部份可能的漏洞。反觀 alpine OS 版本,就找不到這麼多問題。 這是因為 alpine 預設安裝的依賴較少,所以找到的漏洞也少。正所謂,做多錯多,唔做唔錯(大誤)。這其實有好有不好,因為在發生問題時,在 alpine 下可能連基本的除錯工具都沒有。除非大家有完整測試,或者對 alpine 有相當的認識,你才會選擇一個非官方預設的版本。但就以事論事,引用較少的依賴,長久之下的確是不會有那麼多隱患。大家如果有條件,也可以試試 alpine 或其他版本。 前一節我們可以看到,Trivy需要經過 socket 的方式才能存取主機上的 container daemon 操作權。但 podman 作為一個不主張 daemon daemon less,亦主張不需要 root rootless,那麼它該怎樣執行? 其實podman也有user層面上的 socket,而且 trivy 也有對應的方式去轉用第三方 socket 有點像使用遠端主機 socket,但官方並未宣佈正式支援遠端的方式。 具體使用方式,筆者亦已在 steam deck 上測試,使用方式如下。不過因為 steam deck 預設沒有 root,筆者就省略 cache 指令,免得之後要有權限問題要手動清理。 Ref Podman socket activation Trivy Support for rootless podman

Spring Data 關聯型態 01
科技新知
MacauYeah・2024-07-16

筆者身邊的朋友,首次接觸 ORM 的關聯型態時都會覺得很難,筆者自己也是。但在好好地理順它的設計時,就會覺得其實很簡單。 因為篇輻很長,我們先以Code First的角度,先體驗一下ORM程式讀取的便捷性,以及解決一個常見的序列化問題。 雙向存取 例如一個Parent,有好幾個Child @Entity public class Parent ... Parent Primay Key @OneToManymappedBy=quot;parentquot; List children = new ArrayList; TODO add remove @Entity public class Child ... Child Primay Key @ManyToOne Parent parent; 上述的寫法很簡潔,ORM會為你自動加入join column,處理關聯的載入。在讀取Parent時,它的所有Children就可以直接在Java層面讀取,在讀取Child時,它的Parent也隨時取得。也就是,開發人員只要經SQL準備其中一方的資料,另一方並不需要手動準備,它就可以自動按需載入。 RESTFul API 坑雙向存取 Spring Data在Java層面的雙向存取,已經做到很方便。但經常坑到我們的是Spring Data與RESTFul API的混合應用。當我們嘗試經API回傳我們的Parent Json時,API會很聰明地把關聯的Children也變成Json回傳。但他也會把child中的parent不斷重複變成json,變成無限輪迴。 坊間有兩種不同的解決方案,可以防止無限輪迴。 讓Json可以認得已經序列化的元素。@JsonIdentityInfo 讓Json只可以單向序列化serialization。@JsonManagedReference, @JsonBackReference, @JsonIgnore 筆者兩個方向都試過,但首個方法並不通用,至少它不能算是一般常見的無腦Json結構。它需要伺服器、客戶端都懂這如何經IdentityInfo認得重複出現的元素。 而單向序列化,是筆者現時的通用解。在設計RESTFul READ API時,筆者就會決定到底是Parent自動回傳Child,還是Child自動回傳Parent。決策的考慮因素,主要在於是否可以簡化Client的API調用次數。通常從Parent出發,自動回傳Child,可以節省API調用。但如果是選項性的結果List of Value,就倒過來。有時候,遇著API需要雙向設計,就只好自己設計DTO資料傳輸對象 Data transfer object, DTO。 例如Parent API,就原封不動回傳原本的元素 @Entity public class Parent ... Parent Primay Key @OneToManymappedBy=quot;parentquot; List children = new ArrayList; @Entity public class Child ... Child Primay Key @ManyToOne @JsonIgnore Parent parent; Child API,就反過來引用。 public class ParentDTO ... Parent Other fields except children public class ChildDTO ParentDTO parent; ... Child Other fields 這種DTO,看起來很麻煩。但其實Spring有提供一個簡便的複制DTO功能,它可以把自動複制兩個class中有同一名稱、同一型別的欄位到另一個class上,不需要逐個欄位明文寫出來。 BeanUtils.copychild, childDTO; BeanUtils.copyparent, parentDTO; childDTO.setParentparentDTO 因為child、childDTO中的parent欄位型別不同,BeanUtils.copy會自動忽略,其他欄位就會自動複制。 註 其實古早的網頁系統設計,DTO的概念一直存取。只是現在RESTFul API的流行,很多框架已經提向便捷的Json轉換。若然平時只需Json單向存取,筆者還是省略DTO的建立。

星穹鐡道:抽角色、組隊簡介
手機‧電玩
MacauYeah・2024-03-13

因為抽卡機率問題,坊間很多建議都基於課金的前題,不是所以有人都可以重複。但這亦不是筆者體驗這遊戲的主要方向,所以筆者集中分享一些主線必定會取得的角色,或盡量以4星的方式組隊。但在說明組隊之前,先講一講基本系統。讓大家知道那些地方有課金機率成份。 基本出戰 本遊戲是團隊戰,最多同時4名角色上場,同一角色不會出現兩次。影響出戰強度的,除了角色本身屬性、技能,還有裝備要求。同一角色可以裝備一款【光錐】,六款【遺器】,達到不同的Buff。 每個角色獨有自己的【命途】技能養成,光錐及遺器則可以交換使用。 在攻略副本時,可以借好友的角色,但依然會限制同一角色不能重疊。而好友的光錐及遺器不能交換。 卡池 在遊戲中有角色【躍遷】,就是抽角色的地方。除主角外,其餘角色都可以經【躍遷】以機率的方式抽取。若抽到重複角色,會轉化為【星魂】,用作提升角色的特殊技能。主角的星魂以遊戲進度獎勵發佈,其他角色暫時都以抽取為主要來源。特殊角色,如【黑塔】有特別支線任務可以取得。 光錐同時在【躍遷】中取得。 遺器則是副本敵人隨機掉落,沒法經抽選擇。而角色命途技能、光錐、遺器養成部份,所需資源都可在遊戲主線或副本取得。所以有限抽取的,就是角色和光錐。 希有度 角色稀有度最低為4星,最高為5星,道具則為有35星。 卡池沒有4星角色保底,只有4星結果保底,每十連抽可以得到4星角色或道具。 組隊目標 4星非洲隊 主線故事中,一定可以獲得 主角(物理,攻)或(第一章最後獲得,火,盾) 三月七(冰,盾) 艾絲妲(火,輔助Buff) 丹恆(風,單體攻擊) 娜塔莎(第一章中後期獲得,物理,奶) 黑塔(支線模擬宇宙獲得,冰,群體攻擊) 艾絲妲原本筆者也以為是抽角隨機獲得的,但以BiliBili Wiki引證,其實是抽角教學中必定獲得的角色,所以道理上各位也一定會有。但有些版本有活動送角色,但似乎地區不一樣有不一致情況,故筆者沒有列出。 三月七 雖然在取得奶之前,主角(物理)、三月七、丹恒、艾絲妲,就是沒有選擇之下的選擇。但其實三月七的盾有隱藏技能,會增加受擊機率,這是變相指定角色吸仇恨換賺能量的做法。她也是在缺奶時最重要假回血手段,所以是一個有長期培養的角色,用來湊雙冰、雙盾或一奶一盾也不錯。 艾絲妲 筆者一直忽略了的一位重要角色,因為她施放攻擊就有機會蓄能,蓄能全體加攻。終結技有全體加速效能,普偏的裝備方向是為她加速加能量,讓她可以再為其他人加速加攻。也因為第一章後,與主角可以組成雙火隊,主角可以全隊加盾,艾絲妲加速,打火弱點敵人的話,一定不虧。 娜塔莎 奶,就不用說明了。另外,她也作雙物理的組成。也是筆者作為平常無腦開荒的組成,主角(火,盾 加 三月七 加 娜塔莎 加 弱點輸出。效率可能不高,但勝在無腦。 無腦隊最大的問題是弱點擊破率很低,因為盾和奶都需要經常回復,少了輸出的機會成本。

Spring Boot - Maven Cheat sheet
科技新知
MacauYeah・2024-01-12

基礎 刪除所有結果,全部重新編譯 mvn clean compile 跑起用Spring boot寫的main class,運行Spring boot context。 mvn springbootrun # or mvn clean compile springbootrun 執行測試用例,預設只會測試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 springbootrun PmvnProfile 使用pl限定mvn指令只對某個子組件生效,但有時候子組件之間也有引用關係,所以需要再額外加上am參數alsomake mvn clean compile springbootrun 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,種到本機電腦中的.m2repository # copy from httpsmaven.apache.orgguidesminiguide3rdpartyjarslocal.html mvn installinstallfile Dfile= DgroupId= DartifactId= Dversio

街霸六的元宇宙大笪地對戰大廳
手機‧電玩
MacauYeah・2023-12-26

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

今時今日,課金手遊值得遊玩嗎?
手機‧電玩
MacauYeah・2023-10-20

原本筆者想做一個掌機遊戲 Switch,Steam Deck, Mobile Phone的詳細對比,但最近手機的手遊真的讓筆者有太多感受,所以筆者先直接聊一聊遊戲機制問題。 說實話,手機 Mobile Phone這個載體,一定是受眾最廣的。非競技類免費課金遊戲讓大家最開心,下載不用錢,開局刷首抽,不課也開心。而對於鍾情遊戲,用課金買資源,理應亦是符合輕、重不同情度的玩家。走一次性買斷路線的遊戲,也適合無網路情境。 免費課金遊戲又分兩大類,一些是買消耗道具,提供提示或額外資源,一些就是抽獎制,把某些特別資源限制在低機率的彩池當中。以最近的Monster Hunter Now為例,就是走前者路線。可以買回復藥或增加素材的道具,供特殊情境使用。以星穹鐵道為例,就是抽獎制,某些特別角色需要從彩池中抽出。 Monster Hunter Now鼓勵大家走出門,多去一些不同的地方,原意是好的。星穹鐵道設定階段等級上限,讓特殊角色跟普通角色差異有個限度,原意也是好的。上述兩個例子,都是鼓勵大家享受遊戲基礎玩法,不需要每一刻都想著課金問題。而筆者心中的強烈反轉點,亦是因為玩了這兩款遊戲,才爆發出來。 手遊發商始終要找到收益的來源,所以通過設計一些心理關口,等玩家忍不住的時候,就課金下去。營運需要金錢,合理回收成本,大家都應該可以理解。筆者對於之前一款競技手遊,也本著支持支持的態度,去課金兩三輪。因為遊戲課金目的很明確,就是提前解鎖指定角色。筆者課出去,亦玩到想玩的角色,大家都合乎預期。 但問題是MHN和星穹,雖然看似課也能玩,但實際上,兩者玩下去都很痛苦。MHN的資源囤積速度很慢,選錯武器走錯開發路線,想換武器就得花相當大的時間成本。即使課金,也不能取得指定武器素材,也不能指定出現的魔物,使課金的確定性變得很低很低。 星穹也類似,遊戲原本就有每日取得資源上限。課金可以抽多個角色,但無法讓你重塑角色。在資源有限的情況下,你不單要考慮養那個角色,還要考慮養哪個技能,壓力也真大。到後來,可能你更在意資源收益,去猛翻功略找養成策略,而不是去研究過關機制。 這還引伸另一個問題。我課金,為了更好地享受遊戲,隨時想玩就玩,忙的話,就先不玩,有時間,就多玩玩,但上述兩遊戲都不行。MHN課金道具染色球,亦需要玩家無時無刻打開遊戲,在指定的時空標記魔物。有空想多打兩場?不行。星穹的課金模式還有分一次性和月票制。月票制雖然每日資源變多,但你若很忙,沒時間玩,那天的資源就會浪費掉。之後即使你很閒,也不能多玩。 或者有人會說,無限課金不就解決問題了嗎?但這樣的話,筆者寧願支持買斷制遊戲,至少一次性付費之後,不論怎樣重塑,也是在連續的時間內可以重來的事,再加上對機制上的熟習,多次重塑的時間會會更短。 即使講了這麼多的不是,上述兩遊戲還是相當出色的。MHN以動作遊戲規格來看,是非常能發揮手機的便攜性同時能以最直觀的方式去實作動作遊戲的刺激感。星穹的聲畫演出絕對是上上成,回合制戰鬥並不讓玩家覺得沉悶。但兩遊戲的問題就是課金收益讓人蛋疼非常。 或許,之後筆者還是會出一篇掌機遊戲大評比,但可能課金手遊就不在對比範圍裏面,能比的就只有一次性付費遊戲

Miffy米菲控必去-澳門上葡京MIFFY創意展
生活在我城
MacauYeah・2023-10-17

唔知點解上葡京會唸到搵米菲做主題,哩隻來自荷蘭的公仔一直低調地遊走唔到國家但係澳門真係比較少出現,但相信米菲控一定知道佢係荷蘭同日本有幾受歡迎話說上葡京今次舉辦的MIFFY創意展由9月25日至11月12日係酒店舉行,場內唔同地方有超過100隻Miffy,還有 #Miffy主題下午茶、文創禮品、親子工作坊等,集打卡、美食、購物等等。 身為米菲控的筆者當然要帶埋佢個嫰B去探望吓咁可愛的米菲 周六1200首先去到酒店大堂酒廊嘆翻個 ldquo;Miffy 主題下午茶rdquo;費用MOP26815%,供應時間1100至1800再加點一個大蝦意粉先 落單後,係附近影吓靚相,之後好快等到飲品 圖1. Miffy Latte OMG好靚好靚好靚呀飲落還可以但沒有很驚豔。 圖2. Miffy Orange Ballon 香橙啡一望有點疑惑,但飲落特別可以哦很香橙味的咖啡。 圖3. 大蝦意粉 一大碟,小小辣,味道OK 圖4. Miffy吐司配雪糕 終於等到最期待的吐司,看着很美嘛,食落hellip;..外皮不脆,內里算軟,但除了上層有雪糕味,包有包味外,應該算是有點失望hellip;hellip; 圖5. Miffy朱古力焦糖撻 很美表面是甜甜的焦糖,下層是濃濃的朱古力,很甜甜的一道甜品 圖6. Miffy甘筍蛋糕 嗯以經有點飽,但咁可愛一定要試,係清香的甘筍味,蛋糕很軟。 食到一半,可愛的主角米菲登場,係場內大方同大家影相呀 嫰B更然立即衝埋去影相同摸摸啦 總結兩大一小食哩個餐一個意粉有點多,建議單點自己想食的都很足夠不一定要點餐,但米菲控叫一個主題餐是常識吧哈 食完仲可周圍行吓,場內仲有好多不同大小設計的米菲公仔同精品,歡迎大家一齊黎同米菲見個面哦 資料補充 上葡京官網 httpswww.grandlisboapalace.comtcrestaurantsnbarsglplobbylounge 餐廳不可預訂, 餐廳登入澳娛會員有95折(可以提前登記) httpssupremecard.sjmresorts.comtcmymembership

Docker Swarm mode 指令教學 | docker service
科技新知
MacauYeah・2023-08-22

之前一直都討論Image 的打包形式,現在聊聊部署上線時的一些指令。 Docker Service swarm mode 主要通過quot;docker servicequot; 指令去產生一堆可以在不同節點上運行的container。為了更加形象地講,我把container稱為Image的分身。 docker service create跟docker container run的感覺很像,兩者都可以指定image # swarm mode $ docker swarm init $ docker service create name nginx_s nginx # container mode $ docker container run d name nginx_c nginx 兩者的差別在於docker service 可以指定多少個分身,可以隨時加減數目,而且如果你有多過一台機器,分身就會在不同的機器上遊走。而docker container就是只對本機有操作,也不會散播到其他機器。 # swarm mode $ docker service create replicas=2 name nginx_s nginx $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS uro4rwy6nelh nginx_s replicated 22 nginxlatest $ docker service update replicas=5 nginx_s $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS uro4rwy6nelh nginx_s replicated 55 nginxlatest # container mode $ docker container run d name nginx_c1 nginx $ docker container run d name nginx_c2 nginx $ docker container run d name nginx_c3 nginx $ docker container run d name nginx_c4 nginx $ docker container run d name nginx_c5 nginx $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c45771f06612 nginx quot;dockerentrypoint.hellip;quot; 7 seconds ago Up 6 seconds 80tcp nginx_c5 a587a718da3a nginx quot;dockerentrypoint.hellip;quot; 9 seconds ago Up 9 seconds 80tcp nginx_c4 079f206f8645 nginx quot;dockerentrypoint.hellip;quot; 9 seconds ago Up 9 seconds 80tcp nginx_c3 e10dc525fd22 nginx quot;dockerentrypoint.hellip;quot; 10 seconds ago Up 9 seconds 80tcp nginx_c2 dcaa2b4bb3de nginx quot;dockerentrypoint.hellip;quot; 10 seconds ago Up 9 seconds 80tcp nginx_c1 在建立網段時也差不多,service需要的是overlay network,而container用一般network就可以。 # swarm mode $ docker network create driver overlay nginx_s_gateway $ docker service update networkadd name=nginx_s_gateway,alias=gateway nginx_s $ docker service ps nginx_s ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS fxqtheyvr914 nginx_s.1 nginxlatest dockertest Running Running 33 seconds ago u0pvj1leoizw _ nginx_s.1 nginxlatest dockertest Shutdown Shutdown 33 seconds ago q7arumjlxduv nginx_s.2 nginxlatest dockertest Running Running 36 seconds ago kurlwqfmopbg _ nginx_s.2 nginxlatest dockertest Shutdown Shutdown 37 seconds ago zd0zlkhxafv0 nginx_s.3 nginxlatest dockertest Running Running 40 seconds ago 3kapr00fs6pt _ nginx_s.3 nginxlatest dockertest Shutdown Shutdown 40 seconds ago 5o4afd3whygo nginx_s.4 nginxlatest dockertest Running Running 35 seconds ago oxocropolbo8 _ nginx_s.4 nginxlatest dockertest Shutdown Shutdown 35 seconds ago x5y94jf3ok51 nginx_s.5 nginxlatest dockertest Running Running 38 seconds ago cgld3au0w1i9 _ nginx_s.5 nginxlatest dockertest Shutdown Shutdown 39 seconds ago # container mode $ docker network create nginx_c_gateway $ docker network connect alias gateway nginx_c_gateway nginx_c1 $ docker network connect alias gateway nginx_c_gateway nginx_c2 $ docker network connect alias gateway nginx_c_gateway nginx_c3 $ docker network connect alias gateway nginx_c_gateway nginx_c4 $ docker network connect alias gateway nginx_c_gateway nginx_c5 不過比較大的差異是service會停了原有的分身,重開新的分身去加入網段。所以上面的docker service ps nginx_s執行結果,就有一半是停掉的。 類似地,docker service也不能單獨地停掉分身,頂多只能調整replicas=NUMBER,來控制分身數量。而單機則可以經過docker container stop來暫停分身。

自己架設Docker的共享儲存空間
科技新知
MacauYeah・2023-07-21

Docker很好用,在單機環境下真的很好用。Docker原本的設計,是為了快速迭代而設計成Image的。在一般設定下,每次新建或重建container,都會根據Image重設一下各方面的環境,包括儲存空間。重設CPU,Memory,大家都很易理解,但重設儲存空間,真的不是每一個使用情況都可以這樣。 又或者說,未必所有使用情況都會有一個第三方的儲存空間可以用。所以良心的Docker在單機環境下也有提供bind mount或是docker named volume,作為可以長期保存,不受container生死的影響,以達到長期存在Data的存在。 單機儲存空間 單機情況下很簡單,就用一個docker compose做例子 其中html就是一個bind mount,而nginxlogs就是一個docker named volume,兩者都可以長期保存data,除非各位自己手動刪除,否則不會因為container的興亡而不見了。 但有兩個很重要的分別 bind mount,直接跟host os連接,實際上是每次folder有更新,docker都要同步host和container之間的資料。 bind mount在linux下很暢順,因為大部份docker imagecontainer原本就是linux engine,所以folder mount真的可以互通。 bind mount在windows mac下,就會不斷抄資料。面對大量檔案,例如node_module,就會有速度上的問題 docker named volume,就是docker 分離一些獨立空間,然後再綁到container上 相對bind mount,即使在windows mac下,都沒有那個速度上的問題。筆者猜測,即使是獨立空間,其實本身都已經限定在linux enginx下,所以沒有需要抄資料。 但在windows mac下,因應docker 底層建立Linux VM的技術不同,你可能沒法在windows mac預設環境下直接讀取docker named volume。 若要讀取docker named volume,最好的做法,還是連上docker container,然後用docker cp 來抄回資料。一但抄資料,其實都會有速度上問題,不過docker cp是手動決定何時做的,不做docker cp,其實container也是可以用。 Cluster儲存空間 雖然良心的bind mount和named volume解決了單機上的儲存問題,但到了cluster環境,就沒有可以跨機同步儲存空間的做法,要做就自己建立。 筆者也稍為研究了一下同步的問題,不過對技術真的很有要求。所以退而求其次,筆者還是選擇簡單的第三方儲存空間。就是做一個可以分享存取的NAS。 建立nfs linux下要安裝nfs其實很簡單,不過要注意資料夾和防火牆權限,以下安裝教學以ubunut 22.04為例,記得把下面的YOUR_DOCKER_NODE_ADDRESS_RANGE轉為你的真實IP段落 修改docker compose 最後,你在原來的dockercompose的docker volume上加driver_opts就大功告成。 記得把下面的YOUR_NFS_IP轉為你的真實IP

使用 Multipass 建立Docker Cluster
科技新知
MacauYeah・2023-06-02

以下流程,假設各位已經 在Ubuntu Server中開設了virtual bridge 供Multipass設定Static IP,並且network interface定為 localbr 使用Packer template制成docker.img , 並存放於當前資料夾內 使用docker.img 起三個node,並使用network interface localbr,各有一個指定的mac address multipass launch file$PWDdocker.img name node21 network name=localbr,mode=manual,mac=quot;5254004bab21quot; multipass launch file$PWDdocker.img name node22 network name=localbr,mode=manual,mac=quot;5254004bab22quot; multipass launch file$PWDdocker.img name node23 network name=localbr,mode=manual,mac=quot;5254004bab23quot; 對運行中的三個node,為它們設定static ip multipass exec n node21 sudo bash c 'cat etcnetplan10custom.yaml network version 2 ethernets extra0 dhcp4 no match macaddress quot;5254004bab21quot; addresses 10.13.31.2124 EOF' multipass exec n node22 sudo bash c 'cat etcnetplan10custom.yaml network version 2 ethernets extra0 dhcp4 no match macaddress quot;5254004bab22quot; addresses 10.13.31.2224 EOF' multipass exec n node23 sudo bash c 'cat etcnetplan10custom.yaml network version 2 ethernets extra0 dhcp4 no match macaddress quot;5254004bab23quot; addresses 10.13.31.2324 EOF' multipass exec n node21 sudo netplan apply multipass exec n node22 sudo netplan apply multipass exec n node23 sudo netplan apply 使用node21作為Leader Manager,與其他兩個node一起組成Cluster multipass exec n node21 sudo docker swarm init advertiseaddr 10.13.31.21 multipass exec n node21 sudo docker swarm jointoken manager managerToken=$multipass exec n node21 sudo docker swarm jointoken manager q multipass exec n node22 sudo docker swarm join token $managerToken 10.13.31.212377 multipass exec n node23 sudo docker swarm join token $managerToken 10.13.31.212377 Cluster就建立完成。 若想刪掉重來 multipass delete node21 multipass delete node22 multipass delete node23 multipass purge 備註 在直正使用時,大部份時間還需要做port forwarding。multipass沒有自己的port forward,可以用ssh tunnel來模擬。 例如把Ubuntu Server的8080指向node21的8080,可以這樣 sudo ssh i varsnapmultipasscommondatamultipassdsshkeysid_rsa L 0.0.0.0808010.13.31.218080 ubuntu@10.13.31.21 完整的script可以參考initDockerCluster.sh。 沒有Bare Metal Ubuntu或者沒有static ip也可以參考initDockerClusterWithoutStaticIp.sh。只是因為network brandwidth問題,我就不會在每次更新時都測試。

動作遊戲天尊Capcom也做不好的事:打擊感與互動機制
手機‧電玩
MacauYeah・2023-04-14

好多朋友都知道,Capcom出名善於制作動作遊戲,而且它的動作打擊感極好。Monster Hunter,Devil May Cry系列,都是把公認的動作遊戲王者,聲、畫、特效、節奏、打擊感發揮到極致的遊戲。但筆者始終都覺得,它們欠缺了一份重要的東西,它們所謂的打擊感怎好,都像是打空氣一樣。而且萬年不變,代代也是少了一點。然而,筆者玩過Capcom的Street Fighter V,明明就可以把打擊感做到更完美,為何Monster HunterDevil May Cry就怪怪的呢?直到,筆者玩過Sekiro Shadows Die TwiceSIFU等遊戲,才恍然大悟,所以趁機會好好來聊一聊。 傳統上的打擊感 我們先來講講,傳統上的打擊感是什麼?首先,打擊感是通過角色動作、畫面特效、音效等多種元素來實現的。通過對不同狀況下調整視覺和聽覺感覺,讓玩家感受到攻擊打擊動作在不同物件時的合理性,來模擬打擊的感覺。例如:角色在攻擊揮空時,配上劃過的風聲,給人一種動作凌厲的感覺;角色攻擊命中時,動作稍為卡頓,並配上敲打或切割音效,讓人感覺到切實地打中了。更加詳細的,就是角色在受擊時,因應不同的打點,有不同的受擊動作,讓一切都顯示的因為玩家的操作而且互動。 在格鬥遊戲中Street Fighter V中,就完美演繹了上述的各點,所以筆者就覺得很完美。但Monster HunterDevil May Cry,其實都有相應的特效,為何打擊感就差了那麼多? 廣義上的打擊感:互動機制 Monster HunterDevil May Cry,對動作、特效、音效,都制作得很好。但唯獨遊戲的互動機制設計得很差。Monster Hunter系列,每隻怪物都存在霸體機制。需要玩家長期地命中某些攻擊,才會出現倒地或氣絕等狀態。筆者玩下去,就是一種長期打牆的感覺:對對對,你打中了,但感覺像是打空氣。換個角度就是說,但你有你打,它有它存在。你以為自己在玩Monster Hunter,其實你在玩Rockman。而Devil May Cry也差不多,每次Boss戰就霸體連連,連人型Boss戰例如DMC5 M20的Vergil也沒有很好修釋,真的有合理性的只有小兵戰。 Sekiro Shadows Die TwiceSIFU又有何不同?最不一樣的就是敵人會正面防禦。你的攻擊對敵人來說都會被擋著,只有在互相搶攻時才可能被Counter,或是被長期施壓時出現破防(架勢條被打滿而破防)。反過來,你也可以防禦敵人的攻擊,但也會被Counter或破防。敵人要反擊時,通常會先前幾招格檔,然後突然躲掉你的攻擊讓你揮空,又或是直接招架Parry你的攻擊後,才來打你。同樣的,你也可以同相同機制來對付敵人。即使在這種情況下,Boss設計上,它的招式上還是可以保持強勢,依然有很多不一樣的花招、更強的範圍判定。敵我雙方的機制相同,但Boss的設計亦不失霸氣。 兩類遊戲,本質上的差別就在於,Sekiro Shadows Die TwiceSIFU會以格擋和血條以外的機制來處理互動。而Monster HunterDevil May Cry就以霸體、累計暈眩值來處理。 結論:互動要合理 雖然原則上遊戲AI早就掌管好一切,玩家所作的事情也是「被互動」。但在Sekiro Shadows Die TwiceSIFU這種「被互動」制,就明顯地合理很多。你不會覺得在打空氣,頂多是覺得對方AI太強,會更加逼使自己使不同的策略來應對。SIFU在最終Boss設計更顯高明,最終Boss的首階段,會使用與主角一模一樣的招式。與玩家的分別,就只有出招時機和預判。初次遊玩的玩家,一定會很驚訝,原來自己的那一套,還可以這樣用(而且通常都被Boss打得很慘)。 還沒玩過SIFU的朋友,真的可以去一試,Sekiro Shadows Die Twice可能難度更高一些。不過也很值得大家去試。

Devil May Cry 5 DLC 評價
手機‧電玩
MacauYeah・2022-01-07

結論說在前頭,如果各位是DMC的系列老粉,又或是對動作遊戲有點熱愛的話,DMC5 DLC Vergil,絕對是必買的。接下來就詳細介紹一下它的特點。 操作 在操作層面上,他像是Nero與Dante的混合體,有著Nero的直觀近身操作,但武器卻有著Dante的影子。在初期遊玩時,一定會有點混亂,會記錯Dante和Vergil的招式。重要的是,在正編最後M19, M20中的Boss戰中的招式,你都可以親手使用了。只是使出效果和攻擊強度變弱,這就需要各位神操作來彌補。另外,除了焰魔刀和幻影劍之後,你還有拳套可以用。 遊玩性 因為是平行世界的DLC,沒有很多新劇情,只在首章和結尾兩章節加入比較多的新動畫,而中間章節的動畫就被系統自動略過。 但在難度挑戰上就給足誠意。一來因為可以操作原本M19和M20中所有Vergil的招式,二來DLC M19和M20中的Boss也換成了Dante。也就是,你正篇中用Dante花式吊打Vergil,你現在在DLC就會被Dante的花式玩弄。還好這是AI操作,如果換成PVP,我猜我應該不輩子都不能玩到結局。 M19的Dante主要用魔劍和手槍,M20的Dante則主用三戳棍和火箭炮和魂石帽,打著打著,原來Dante花招可以是如此的多。如果你正篇只打普通難度的話,基本上Dante很多招式你都還沒有真正的用會,但普通難度的AI就已經練到爐火純青XD。筆者也是在正編最高難度DMD下,才被逼認清Dante不同武器和風格的用途。Capcom的設計還真強。 如果你本身在正篇有挑戰困難或以上的難度,DLC的話你也不要錯過,因為至少讓你有多30小時的新體驗。以HKD 39的價錢來說,真的很值。其實以正篇的價錢,如果大家有挑戰各難度下的S Rank,也是很化算的,但S Rank的要求實在太高,只挑戰難度通關就很足夠。

元祖洛克人、潛龍諜影V 原爆點|一整個月都讓你有驚喜|Taiwan Speedrun Show
手機‧電玩
MacauYeah・2021-10-12

不經不覺,《Taiwan Speedrun Show》已經開始了十多天啦,你還不知道這是什麼? 其實《Taiwan Speedrun Show》是一個以台灣Speedrun社團主辦的活動,並開放華語區的跑者參加。 本年10月共31天,每天晚上將進行各種遊戲項目的Speedrun,隨時都觀迎花生友們,進來一起觀看神奇的快速通關精彩操作。除了作為觀眾,無論任何項目,只要你覺得準備好了,都可以一起參加Speedrun,推廣給更多華語區的朋友,認識這個競技與表演融合的特別節目。 元祖洛克人 10月11日晚大神「guhaha13」,為我們帶來最初的硬核遊戲「元祖洛克人」的快速通關。那個年代的洛克人,還是上下屏幕交換載入的年代,卻衍生了很多不為人知的Speedrun技巧。這次,更有專業旁述「阿痕」為大家講解元祖洛克人的不同小技巧,這絕對不是平常在看直播就有機會看到的 精彩重播用手機無法自動播放的朋友,可以按這裏或手動跳到23m45s處 暫停鍵是一個很重要的操作 上下共通的畫面 潛龍諜影V 原爆點 這一晚,還有澳門玩家「MacauYeah」帶來他的最愛「潛龍諜影」系列的第五代前傳快速通關。這一代的遊戲,比同系列中其他遊戲都不一樣,因為這代算是一個濃縮版,遊戲一開始就提供了很多元的操作。他還不小心的刷新了自己的最快成績呢,未來應該可以為澳門帶來另一個世界級的銅牌? 精彩重播用手機無法自動播放的朋友,可以按這裏或手動跳到1h8m53s處 10月12日節目預告 今晚將會由台主「boelisk」帶來「雙子星傳奇2」遊戲的Speedrun 想看現場Live,記得按Twitch的遊戲追隨喔 過去幾天發生了什麼?快看這裏