2026年3月22日 星期日

Vibe Coding做到封測了,寫下來紀念一下

Vibe Coding過的朋友都知道,現在用AI來做一個MVP非常便利快速


可是之後呢?是不是發現往商品化的路上越做越舉步維艱?


我以vibe coding形式開發的DC文字冒險遊戲努力做到封測了


跟大家分享一下心路歷程;


1. AI服務:

這個案子使用的AI服務有Gemnini跟Claude,都是有付費的Pro版。


2. AI介入程度:


* **企劃**:介入度約50%

主要用來討論、發想、文本工程、數值模型

Gemnini在敘事部分算是不錯的,背景設定架構好後能很快速的產生質量還行的文本。

雖然質量可以,但還是需要人工review,常常會有小地方不符合設定或怪怪的。


數值模型我不擅長,幾乎都是靠它規劃跟驗算。

數值的話一定要讓AI跑具體程式來驗算,它心算有時會不准。


你不會寫程式?那就叫它生。不過你至少要有能檢查公式是否正確的能力。


* **美術**:介入度約75%

主要用來產出圖片。

本案美術部分相對不吃重,所以相比於Midjourney,Gemnini的Nano Banana勝在比較聽得懂人話,溝通成本較低,且質量可以。

當然,人工調控風格、校準、修瑕等工作還是跑不掉的。


* **程式**:介入度約95%

沒錯,95%,比你一天刷手機的時間比還高。

因為本案使用的語言是python,我可以說是從0開始,因此幾乎都交給AI去寫code,而我主要則負責request、review、以及部分測試。

不過我本來就會其它程式語言,很多概念跟邏輯都是互通,所以幾乎沒費什麼力就上手。(有點像會了英文再學其它歐洲語言的概念)


初期是使用Gemnini,也還挺順利快速的。

不過到中後期就開始乏力,AI反而成為問題來源。

後來換了Claude來處理coding部分才有所改善。


* **翻譯**:介入度約99%

語言這種東西跟數學一樣,不會就是不會,你也只能相信它。

有興趣的朋友可去看看它翻得怎樣,遊戲是免費的。

 

* **營銷**:約25% 

主要用來發想文案。

我其實覺得AI在營銷上很有潛力,畢竟LLM某種程度上來說也是一種大數據的體現,應該會很有用才對。

有看到用AI來海巡的,有考慮嘗試但有些風險,還須評估研究;也有聽說用AI來分析跟投放廣告等等......

不過具體怎麼用好還在研究,然後就跑過來寫這篇了。


對這方面有研究的朋友,歡迎分享你的想法


* **法務**:約??

還沒用到什麼正式case,目前只用來出ToS跟Privacy Policy。




3. 人跑不掉的


上面看下來,好像AI很不錯,大部分都能幫助一半以上的工作。


但是剩下的會有兩種極端:


其一是很阿砸的:比如要去各平台申請以及設定一些有的沒的,像這個案子就要跑Discord App設定、雲端配置、CDN、以及金流等,沒什麼技術性但不得不跑,俗稱管線工程。


雖然最近有看到Google在整合其中一部分,但我想到兩眼一閉交給AI跑還有一段距離。

因為這些部分會很直接的牽扯到"錢"和"權",這就不是AI跑不跑的了的問題了。


其二是很核心的:比如你的產品要怎樣,那些要有哪些不能有。你當然可以讓AI給意見,但拍板最終是你,承受結果的也會是你。


這其實就要求使用者的知識儲備、經驗、以及sense。



以上,一個不是什麼很偉大的vibe coding產品開發心得,紀錄並分享給大家



2026年1月4日 星期日

按鈕的加減法

 在Discord的應用開發中,原生UI的排版限制非常嚴苛,像一行Action Row最多只能放5個按鈕


這可苦了我


在《鍊金術師與瓶中獸》的主控介面裡,第三行是寵物相關的按鈕,完整的應該是


[進化][緊急救治][餵食][交換][瓶中獸煉成][歸原]

不光是塞不下的問題,即使塞的下,一排看來也是又臭又長


如果換行的話,又會斷開行跟按鈕類型的關聯,而且Discord規定最多5行,實在不好放開說換就換


因此這裡就得花點心思:

1. 把平常不會用到的按鈕藏起來

2. 確保同行按鈕數不會超過5


在歸納後,把[進化][緊急救治][交換][歸原]這些使用條件較高且使用頻率較低的按鈕設為條件顯示


因此最初能看到的按鈕只有:


[餵食][瓶中獸煉成]


但最多的按鈕有6個,因此需要設計互斥按鈕


所以就有了"寵物瀕死時不能進化"的規則,使[進化]跟[緊急救治]只能同時出現一個,以達到確保最多5個按鈕的目的,敘事上也說得過去



以上,就是《鍊金術師與瓶中獸》的按鈕設計心路歷程


如果以後有更多的功能,可能就要放在二階頁面裡了吧,當然我是希望盡量避免太多層的操作就是了


2025年12月26日 星期五

AI主理開發,又如何?

 《鍊金術師與瓶中獸》是我第一款AI主理開發的作品

這裡的"AI主理"是指:由AI負責發想內容、調數值、生成程式碼、產出圖片等牛馬工作

而我則負責出腳、眼睛跟手,也就是決定方向、審查與調修

這個案子不大、也不難做,但要說一句話AI就咻咻咻幫你搞定到這種程度,是不可能的


我的主要背景是程式,就講講這部分吧

本案的程式碼99.9%都是AI生的,但不是AI搞定的

什麼意思?

AI確實能照我要求生出程式碼,絕大部分也確實能運行

但其實在走的過程裡它動不動就給你暴力解、時不時就起乩神理解

而且你必須規劃階段,畢竟有些東西要先出來後面的東西才能實現

還有許多效能或架構上的問題,後續發現了才叫它改進


有人可能會說阿你跑SDD啊,用AGENT、工作流、Skills、巴拉巴拉啊

孩子,你不會真的覺得我都沒用吧?不會真的覺得用了就不會有問題吧?

天真!太天真了!

確實,比起單純的下提示詞,加上這些能讓AI更聽話有效

但實際上跑起來抽的風還是不會少

你若沒能力去糾錯、修正,嘖嘖,我是不太敢想會變怎樣

可能以後會越來越好吧,但現在跑起來就是很多雞毛


所以我很好奇,讓沒有程式背景/概念的人來跑這些會怎樣

真的能像網上說的那樣,人人都能出產品嗎?

MVP我想問題不大,但完整的VP呢?後續的維護、疊代呢?



看起來我對AI意見很多,但我必須承認我能接受這些毛病,比接受前妻還能接受

喔對我沒有前妻


回歸正題,上面提的毛病,今天換成人類隊友也是有可能發生,甚至自己也有可能犯

但不同的是AI它快、太快了!

我平均3小時才能出來,AI往往不到3分鐘就出來了

(我說的是正經的產出內容,不要亂想)

再說它不會跟你鬧脾氣耍心眼、不會管你是藍是綠、不會看你是黑是白

甚至你真要這種設定它也可以!

如此,有那麼點毛病好像也不是不能接受


順帶一提我跑這案子開始沒多久就遇上Gemini 3 Flash發布, 之後就一直用,到出版本當天額度剛好用光(當天真的一堆破事,該死的出版詛咒!)

所以其實用挺兇的,雖然也有一部分是我太懶的關係


在美術/企劃方面也是一樣,它能幫我產出不錯的模樣,但我還是得花心力修整

我這兩邊比較不專業,但我想兩方專業人員在用AI協助創作時也是這樣吧

終究還是要靠創作者本人


所以我實在不理解「使用AI而被取消獎項」、「AI就是盜竊」之類的現象跟言論是怎樣

有問題到底是AI,還是人?


好啦,抒發差不多了

最後我必須承認你現在看到的文章是AI

一個字都沒有產生,由我一個字一個字打的,你看我還不小心斷錯行了呢

你信嗎?

信又如何?不信又如何?

是不是AI,又如何?

2025年7月17日 星期四

Unity串廣告 - Unity實作篇

 一段時間沒在Unity串廣告, Unity又升級做法了

寫這篇時是2025年7月,這時新版的做法是用LevelPlay與Ads Mediation

新版可以選擇的廣告商變得更多了, 但是設定也更複雜了


在開始之前提一下,以前的Unity Ads還是可以使用,不過官方不再更新支援,想用可以參考:https://www.goostudio.tw/post/介接unity-ads


接下來就是在Unity專案裡實做廣告串接:

連接Unity Cloud

Unity專案需要連接Unity Cloud才能運行Ads Mediation,連接設定可以參考:https://goocoding.blogspot.com/2025/07/unity-cloud.html

安裝Ads Mediation

在PackageManager中的Unity Registry可以找到Ads Mediation安裝

本篇的版本用的是8.10.0

實作初始化LevelPlay

創建一個腳本運行LevelPlay的初始化,程式碼範例如下圖:

要注意的是,UnityServices初始化完成後才能進行LevelPlay的初始化

還有LevelPlay.Init需要的appKey可以從LevelPlay的後台->Apps( https://platform.ironsrc.com/partners/home )找到

如果後台沒有的話,可以參考此篇設定:https://goocoding.blogspot.com/2025/07/unity-levelplay.html

實作廣告呼叫

接著實作廣告的讀取與呼叫

本範例的腳本是綁在(UGUI的)Button物件上,點擊時呼叫ShowAd()

如果你沒有Button物件的話,我建議你有

程式碼範例如下圖:

其中new LevelPlayRewardedAd時要用到的adUnitId可以從LevelPlay的後台->Setup->Ad units

( https://platform.ironsrc.com/partners/next/adUnits/ )找到

後台的ad unit設定可以參考此篇: https://goocoding.blogspot.com/2025/07/unity-levelplay.html

在這個範例中,你可以利用AdsCompleteEvent來呼叫廣告播放完成後的遊戲邏輯(ex: 復活、給次數、etc...)

2025年7月16日 星期三

Unity串廣告 - LevelPlay設定篇

 一段時間沒在Unity串廣告, Unity又升級做法了

寫這篇時是2025年7月,這時新版的做法是用LevelPlay與Ads Mediation

新版可以選擇的廣告商變得更多了, 但是設定也更複雜了

在開始之前提一下,以前的Unity Ads還是可以使用,不過官方不再更新支援,想用可以參考:https://www.goostudio.tw/post/介接unity-ads

那麼接下來是正式的串接內容:

LevelPlay設定

LevelPlay 是 Unity 與 ironSource 合作推出的 廣告變現與媒合平台,也是新板作法所用的平台

用Unity帳號登入:https://platform.supersonic.com/partners

新增App

由Apps -> Add app新增你的App

頁面選項如圖:

2025年7月13日 星期日

使專案連接Unity Cloud

 Unity Cloud 是 Unity 推出的雲端平台服務總稱,整合了開發、測試、部署、營運與協作等功能

一般來說在創建Unity專案時預設是開啟的



如果你沒開但在事後想使專案連接Unity Cloud,那有兩種方法:

1.使用Unity Hub

在Unity Hub中,點選專案的雲端圖標或按右鍵,皆可設定連接Unity Cloud


2.在Editor中設定

點選 Editor-> Project Setting->Servies,即可選擇連結已有的cloud專案或(以此專案)創建新的cloud專案



2023年7月5日 星期三

介接Unity Ads

在行動平台中, 放廣告是一種常見的收益方式

而用Unity開發時除了使用一些插件來植入廣告外, 其官方本身也有提供廣告插放的服務

本篇將介紹如何介接Unity Ads, 並實作一個獎勵式廣告作為範例


另外本篇是使用Unity 2023.3版本為範例, 不過這個功能很早之前就有了, 相信早幾個版本的也是大同小異


1.啟用Server與創建Unity Project

要使用Unity Ads, 首先必須啟用Unity Gaminig Services


打開你的Unity專案, 在Project Setting中選擇Services

選好組織機構(Organizations)後, 即可點選Create project ID, 在Unity Gaminig Services中就會創建一個跟你專案目錄一樣名稱的專案並與本地專案檔聯繫起來


2.取得Game ID

Game ID是產品在各平台中對應的ID, 要有這個才能初始化Unity Ads


開啟 https://dashboard.unity3d.com/  , 選擇Monetization後選擇要設定的專案

點選Get Started後會開啟設定視窗, 第一頁是選擇你的中介方案與廣告商

第二頁是選擇廣告設定, 有關用設定的可以沿用先前專案的設定, 本篇是用新的開始

第三頁是選擇投放策略, 選你喜歡的就好

第四頁是設定設定產品在平台中的商店ID

還沒上架時可以先選"My app is not live in an app store yet", 不過上架完要記得回來補齊喔

接下來按下Add project就可以取得Game ID了

於此後台就設定的差不多了, 回到Unity Editor繼續作業


3.導入Advertisement

Advertisement就是Unity Ads的SDK, 支援Android跟iOS平台

開啟 Window > Package Manager, 搜尋Advertisement並安裝(Install)



4.初始化

Runtime時要先初始化Unity Ads才能運作

創建設定Game Id與初始化的腳本AdsInitializer



5.實作獎勵式廣告

所謂的獎勵式廣告就是使用者在觀看完廣告後能夠獲得一些獎勵


本篇將實作一個獎勵式廣告按鈕腳本(示範平台為Android), 其正常流程為:

讀取廣告->使用者按下廣告按鈕->顯示廣告->廣告播放完成->使用者獲得獎勵


創建廣告按鈕腳本RewardedAdsButton


在場景上建立一個UGUI的按鈕, 先關掉該按鈕物件


將AdsInitializer掛在Main Camera上, 設定Game Id與InitializationCompleteEvent(把按鈕開啟)

P.S. 在產品上線時記得把Test Mode勾掉

將RewardedAdsButton掛在Button上, AdsCompleteEvent就是設定廣告播完後你要做的事


以上, 順利的話在run time按下廣告按鈕後會看到:


參考資料: https://docs.unity.com/ads/manual/UnityAdsHome 

2023年4月28日 星期五

利用Steam統計來實作Steam成就

Steamworks有提供統計功能, 讓開發者可以便捷的將玩家遊玩的數據紀錄下來(ex: 破關次數、通關時間, etc...)

此功能同時也能連動於Steam成就, 也就是可以實現"當玩家的某個統計數據達到某個值後, 解鎖某個成就"

應用此機制, 開發者可以於程式中只實作統計紀錄, 將資料儲存、成就達成判斷、和成就解鎖這些事交給後台

下面將說明如何實作:

後台設置

本篇假設開發者已於Steamworks建立應用程式
1. 從Steamworks的主控台選擇要設置的應用程式, 進入其 技術工具->編輯Steamworks設定 頁面
2. 進入 統計與成就->統計 頁面, 新增統計欄位, 設置API名稱等資料
3. 進入 統計與成就->成就 頁面, 新增成就欄位, 設置API名稱等資料
4. 於成就欄位中的 進度數據 一欄選擇要參考的統計API
5. 將解所成就的條件值設定於最高欄位, 當參考的統計API數值達到其以上時, 即解鎖成就
(比如你希望玩家的T1_COUNT達到10以上實獲得成就, 就設定10)
(筆者一開始搞錯設定在最小值, 最高沒設定, 結果就造成了悲劇)

6. 發佈變更使設定生效

程式實作

本篇是於Unity中使用Steamworks.NET來實作, Steamworks.NET的導入與初始化不於本篇贅敘, 直接進入API使用環節
1. 使用SteamUserStats.SetStat, 設定值於指定的統計API
2. 如希望在玩家能即時得到成就解鎖, 設定完Stat後要呼叫SteamUserStats.StoreStats, 否則會在關閉程式時才會把資料傳給後台

2022年9月8日 星期四

[雜記]搬Discord bot到Azure上

 原本是把Discord bot放到Replit上跑, 不過最近常遇到Replit上還在跑但bot已經下線的情況, 即使重新執行了、也沒報錯, bot還是沒有上線的奇怪情況


經過友人的指點, 才知道這是類似429 too many requests的問題, 是由於共享ip被用太多而造成的, 只能透過kill 1之後重新執行來換ip解決

後來實在太頻繁發生了, 於是就有了把bot搬到其它雲端的想法, 後來就決定試試搬到Azure
不過畢竟對server不熟, 花了好多時間採坑才弄好, 特此紀錄

2022年8月25日 星期四

[Discord]機器人的的login與接收訊息/反應(discord.js:14.3)

 最近又開始寫起Discord機器人, 用的discord.js是14.3的版本, 跟上次寫的時候用的12.3版有一些差異, 於此記錄一下


Login

12.3的login:
const { Client } = require('discord.js'); const client = new Client({ partials: [/*需要的partial字串, ex:'CHANNEL'*/] }); client.login(/*機器人的token*/);

14.3的login:
const { Client, GatewayIntentBits, Partials } = require('discord.js'); const client = new Client({ intents: [/*需要的GatewayIntentBits列舉, ex:GatewayIntentBits.Guilds*/], partials: [/*需要的Partials列舉, ex: Partials.Channel*/] }); client.login(/*機器人的token*/);

2021年3月15日 星期一

[Unity]Game Window的Aspect ratio與Fixed Resolution

Game Window是Unity編輯器中用來顯示玩家視角的視窗,常用來在編輯器中檢視run time時玩家的視角。

其左上有一欄位為調整該視窗顯示用的解析度或長寬比,預設是Free Aspect(不固定比例),意即

2020年10月4日 星期日

[Unity]In-App Purchasing使用教學-Android@Google 篇

In-App Purchasing是Unity提供的跨平台IAP服務

本篇將介紹如何使用In-App Purchasing設定到Google Play Developer Console的商品

本篇教學軟體環境如下:

2017年10月8日 星期日

[Unity]Resources.Load效能測試

儘管官方自己都說不建議使用Resources資料夾, 但是在能取代其便利性的資源載入方案出現前, Resources資料夾仍是我們有快速開發需求時的好朋友

我們使用Resources資料夾內資源, 常用步驟為:

2017年9月9日 星期六

[Unity]物件 顯示/隱藏 之簡易效能評比

我們要在Unity控制物件於畫面中的顯示/隱藏時, 主要方法有:
  • 使用GameObject.SetActive直接開關整個GameObject
  • 開關GameObject上的Render
  • 將GameObject移進/移出畫面

2017年6月4日 星期日

[Unity]Remote Settings 簡介與實作

這篇的Remote Settings不是那個裝置與Unity Editor連線測試的Unity Remote呦, 他是 Unity Analytics Service 底下的一個功能😄

Remote Settings提供開發者一個方便更新數值的管道, 可以不必跟新輸出檔、不必自己架server, 即可實現遊戲數值的熱跟新, 而且目前是免費的

2017年4月27日 星期四

[Unity]AssetBundleManager & AssetBundleGraphTool 之整合使用

AssetBundle Manager是官方提供的bundle管理器, 能夠方便的讀取, 以及模擬測試bundle, 可從Asset Store免費下載(https://www.assetstore.unity3d.com/en/#!/content/45836)


AssetBundleGraphTool 則是Unity日本開發的圖形化打包工具, 能夠很輕鬆的設計自動化打包流程, 也是開源免費(https://bitbucket.org/Unity-Technologies/assetbundlegraphtool)


AssetBundle Manager有附帶快速打包的工具, 但我們必須為要打包的物件設定包名(甚至variants)

2014年8月28日 星期四

[Unity][C#]2 simple ways of load the data form XML // 兩種簡便讀取XML資料的方法

假如今天要讀取路徑為Resources/test.xml 的XML, 內容如下:
For example, the XML data we want read as below, the path is "Resources/test.xml":

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ROOT>
<table wave="1" level="1" name="aaa"/>
<table wave="2" level="1" name="bbb"/>
</ROOT>

我們有兩種簡便讀取的方法:
We have 2 simple ways can use:

2014年4月4日 星期五

[CleanCode]Adjust your if-else//整頓你的if-else

判斷流程複雜時, 我們會需要很多層if-else在程式裡, 最後很容易變成如下又肥又醜的模樣:
We need  many if-else struct when the flow is complicated, then the struct of program will become big and ugly, as below:

 if(A)

{
      do A-1...
      if(B)
      {
            do B-1...

            if(C)
            {
                  do C-1...
            }else{
                  do C-2...
                  return...
            }
      }else{
            do B-2...

            return...
      }
}else{
      do A-2...

      return...
}


真是讓人看得眼花撩亂, 不是嗎?
These make us dazzle, isn't it?

其實我們可以換種寫法:
Actually, we can change a way:

if(!A)

{
      do A-2...

      return...
}

do A-1...

if(!B)
{
      do B-2...

      return....
}

do B-1...

if(!C)
{
      do C-2...

      return...
}

do C-1...


程式運作的邏輯一樣, 但看起來是不是好讀多了呢?
The logic program operating is same, but it become much good to read.

這種技巧是把做完可以直接return的判斷式獨立出來; 利用"return後下方的程式碼不會執行"的特性, 使程式的結構脫離if-else必須一層包一層的窘境
This way is separating the statement which process return when operating done; the code struct can be breaking away the dilemma of if-else layer packet layer, by using the feature of "program will not execute the codes after return".

如此, 我們可以在看多層判斷式時不必再辛苦的對照程式碼在哪一層判斷式 , 大大增加了程式的可讀性
So we don't need to look for codes in the multi-layer predicate, it increases the program's readability.

=======================
希望這對你有幫助,歡迎提供建議
Hope this help you, welcome to advice me.

2013年11月2日 星期六

[Java]Rlease--G Clock1.1

我為G Clock增加了一些功能並釋出1.1版
I increase some functions of G Clock and release the version to 1.1

Update Items:
1. Increase a ComboBox, user could select 2 models to set alarm:
        1.Countdown  
        2.Timing


2.Increase input columns of "Now Plan" and "Next Plan", user could input their simple plan for remain.
3.Increase a button for quickly update "Next Plan" to "Now Plan".

Codes:

The codes of Timing model as below:

2013年10月20日 星期日

[C#]About the way of trace the value of Rectangle.Fill //關於追蹤Rectangle.Fill值的方法

      我最近在研究用C#跟XAML開發 Windows phone APP, 不過遇到了些困難, 其中一個就是我找不到可以直接追蹤Rectangle.Fill值的方法

      I study of Windows phone APP development with C# and XAML nearly, but I experience some troubles, one of them is we have no way to trace to the value of Rectangle.Fill immediately.

      我能理解設計者必須站在高處為開發者考慮通用的功能;矩形不只能填充單一色彩, 也能填充漸層甚至更複雜的圖案, 所以要設計一個參數或者方法去得顏色的值是很困難的

      I can understand that designer need concern the general function for developers; the rectangle not only could be filled with one color,  but also could be filled with linear gradient or even more complicated picture, so it's hard to design a property or a method for show the value of color.

      不過我的要求其實很單純, 我只是要取得Rectangle.Fill的值, 我們只能給Rectangle.Fill設一種顏色對吧?不需要複雜的方法去比較每一個像素, 只需要一個參數去儲存色碼, 為什麼我們沒有方法去追蹤Fill的值呢?