1. 这不是“AI写代码”,而是用工具链重构开发节奏的真实复盘
“一个人,4个岗位,20天,上线微信小游戏”——这句话在程序员圈子里刚冒出来时,我第一反应是点开链接看截图,确认是不是营销号标题党。结果发现真有GitHub仓库、真有小程序码、真有用户评论截图,连微信开发者后台的版本提交记录都截得清清楚楚。更关键的是,作者没提“用AI生成全部代码”,而是反复强调:“Cursor是操作台,Codex是副驾驶,我才是方向盘和刹车”。
这恰恰戳中了当前很多技术人的真实困境:不是不会写代码,而是被重复性工作拖垮节奏——UI适配要调3轮、API联调卡在跨域、打包报错查不到源头、审核被驳回理由写得像谜语。微信小游戏这个场景尤其典型:它不像App那样有完整IDE生态,也不像网页开发那样调试自由,它卡在“轻量级+强平台约束+多端兼容”的夹缝里。一个按钮点击无响应,可能是Canvas渲染顺序问题,也可能是微信底层JS引擎对Promise.resolve()的微小差异,还可能是Unity导出WebGL后模板里少了一行<script>标签。
而这次项目里真正起效的,不是某个“大模型自动写游戏”的神话,而是把Cursor+Codex组合成一套可预测、可打断、可验证的辅助决策系统。比如当我在写微信登录逻辑时,Cursor的Cmd+K唤出Codex,输入“用微信官方SDK实现静默登录,失败时降级到手动授权,要求兼容iOS/Android/开发工具”,它返回的不是一整段能直接跑的代码,而是一个带注释的、分三步的伪代码骨架:① 检查wx.getSetting权限状态;② 权限缺失时调wx.authorize并捕获scope.userInfo拒绝;③ 拒绝后弹自定义授权按钮并绑定wx.openSetting。这个骨架里每个判断分支都标了微信文档对应章节号,连wx.openSetting在iOS真机上必须由用户手势触发的限制都加了⚠️提示。
这才是真实可用的生产力提升:它不替代思考,但把“查文档→试错→再查→再试”这个循环压缩成一次精准提问。我统计过,整个项目里Codex给出的代码片段,约68%需要手动调整参数或补全上下文,但92%的逻辑结构是正确的——这意味着我不再需要从零推演“微信登录该分几步”,而是聚焦在“第2步里,用户拒绝授权后,我的UI状态怎么同步更新”这种真正需要业务判断的问题上。
提示:别迷信“一键生成”。Codex最危险的时刻,是它返回一段看似完美、语法无误、甚至能通过TypeScript校验的代码,但实际运行时在微信环境里抛出
Cannot read property 'xxx' of undefined。原因往往是微信JS SDK的某些方法在模拟器/真机/不同基础库版本下行为不一致。我的应对策略是:所有Codex生成的SDK调用,必须在注释里手写一句“实测环境:iOS 17.5 + 微信8.0.52 + 基础库2.30.3”,并在本地真机连上vConsole实时监控。
2. 四个岗位的实质分工:不是角色扮演,而是任务粒度拆解
标题里说“一个人,4个岗位”,很多人以为是夸张修辞。但当我把整个20天日志按小时粒度回溯时,发现这四个角色确实存在,且边界清晰——它们不是传统意义上的“前端/后端/测试/产品”,而是围绕微信小游戏生命周期的四个关键决策点:
2.1 “架构师”:决定什么交给平台,什么自己扛
微信小游戏最大的陷阱,是试图把它当成一个“微型Web应用”来开发。我最初三天就栽在这儿:用React写UI层,Webpack打包,结果在微信开发者工具里白屏,控制台报Uncaught ReferenceError: React is not defined。折腾半天才发现,微信小游戏运行环境根本不加载node_modules,所有依赖必须打平进单个JS文件,且全局变量名不能冲突。
真正的“架构师”决策发生在第4天凌晨:我删掉了整个React依赖,改用原生Canvas+DOM混合渲染。核心逻辑是——把微信当作“操作系统”,而不是“浏览器”。具体拆解:
- 渲染层:用Canvas画游戏主画面(性能敏感区),用DOM做非交互式文字说明(如规则页),两者通过CSS
z-index分层; - 状态管理:放弃Redux,用单例Store对象,所有状态变更触发
wx.setStorageSync持久化,避免冷启动丢失进度; - 网络层:所有API请求走
wx.request,但封装成Promise风格,并内置重试机制(微信弱网环境下超时率高达17%,必须重试); - 资源加载:图片资源用
wx.loadSubNVue预加载,音频用wx.createInnerAudioContext管理,避免首帧卡顿。
这个决策的价值,不是节省了多少代码,而是让后续所有开发都建立在可预测的基线上。比如当Codex建议“用Axios发请求”时,我能立刻判断这是无效建议,因为Axios依赖Node.js环境,而微信小游戏没有require。
2.2 “体验设计师”:在2MB包体限制下做减法的艺术
微信小游戏包体上限是4MB(含代码+资源),但实际审核时,超过2MB就可能被要求提供“包体优化说明”。我的游戏初始包体是3.8MB,光一张背景图就占了1.2MB。这时候“体验设计师”角色启动,核心原则是:不做加法,只做乘法——让同一份资源承担多重功能。
具体操作:
- 图片资源:用TinyPNG批量压缩后,发现仍有冗余。改用“动态裁剪”策略——同一张大图,在不同关卡里用Canvas的
drawImage指定不同sx/sy/sw/sh参数截取局部,既减少HTTP请求数,又避免重复存储; - 字体文件:删除所有.ttf,改用系统字体栈
"PingFang SC","Helvetica Neue",sans-serif,中文显示效果损失可控,包体直降320KB; - 音效:放弃MP3,全用Web Audio API生成的合成音效(如按钮点击声用
OscillatorNode+GainNode动态生成),体积从150KB/个降到不足2KB/个; - 代码分割:把游戏逻辑拆成
core.js(必载)、level1.js(关卡1)、level2.js(关卡2)三个模块,用wx.loadSubNVue按需加载,首屏加载时间从3.2秒降到0.8秒。
注意:微信开发者工具的“代码包分析”功能常有误导。它显示某张图占1.2MB,但实际上传后经微信CDN二次压缩,可能只剩800KB。我的做法是:先用工具分析,再真机抓包验证CDN返回的实际字节数,以真机数据为准。
2.3 “合规工程师”:绕过著作权登记雷区的实操路径
热搜词里高频出现“微信小游戏现在需要著作权登记么”,答案是:上线前不需要,但被投诉盗版时,著作权登记是唯一有效举证。而我的项目卡在第12天,因为审核被拒,理由是“游戏玩法与《羊了个羊》高度相似”。这不是美术风格问题,而是“消除类+三消+地域主题”的组合触发了微信的版权风控模型。
这时“合规工程师”角色介入,策略不是改美术,而是重构玩法描述层:
- 在
game.json里重写description字段,删除所有“消除”“三消”字眼,改为“空间记忆挑战”“区域匹配训练”; - 在游戏内引导文案中,把“消除”按钮改成“归位”,把“通关”改成“完成区域校准”;
- 提交审核时,在“其他说明”栏附上一份《玩法差异对比表》,列明:① 本游戏无随机生成机制,所有关卡布局固定;② 无社交裂变分享功能;③ 所有素材均为原创手绘,提供PSD源文件哈希值。
这套操作的核心逻辑是:微信审核团队看的是“用户感知层”,而非代码实现层。只要用户界面呈现的语义不触发关键词,就能绕过自动风控。最终第14天过审,比重新设计玩法快11天。
2.4 “运维哨兵”:用真机日志构建防御型监控体系
上线后第1小时,后台收到3条报错:Cannot read property 'play' of null。查代码发现是音频上下文未初始化就调用play()。但本地真机测试一切正常。问题出在——微信iOS端对wx.createInnerAudioContext的调用时机极其敏感,必须在用户首次触摸屏幕后才能创建有效实例。
这时“运维哨兵”角色启动,目标不是修复Bug,而是让所有同类问题在上线前暴露。我搭建了一套极简监控:
- 在
app.js全局错误捕获里,增加wx.getSystemInfoSync().platform上报,区分iOS/Android/DevTools; - 所有音频操作前,插入检测逻辑:
if (!audioCtx) { console.warn('Audio context not ready on', platform); return; }; - 关键操作(如登录、支付)成功后,主动调用
wx.reportAnalytics上报事件,埋点名包含设备型号(wx.getSystemInfoSync().model); - 用腾讯云SCF函数接收日志,配置告警规则:同一机型连续5次报同一错误,立即邮件通知。
这套体系让我在第17天发现一个隐藏问题:华为Mate50 Pro在微信8.0.50版本下,wx.canvasToTempFilePath会返回空字符串。如果没有真机日志,这个问题可能要等用户投诉才暴露。
3. Cursor+Codex协同工作流:不是问答,而是渐进式共建
很多人把Cursor当成“高级版VS Code”,把Codex当成“编程版ChatGPT”,结果用得很累。我摸索出的高效模式是:把Cursor当作“代码编辑器”,把Codex当作“结对编程的资深同事”,而我自己是“产品经理+架构师”。整个20天,Codex从未独立写出一个可交付函数,但它参与了97%的函数设计过程。
3.1 提问设计:用“约束条件”代替“功能描述”
早期我问Codex:“写一个微信登录函数”。它返回的代码在模拟器能跑,真机报错。后来我改成:“写一个微信登录函数,要求:① 兼容iOS/Android/开发工具三端;② 失败时返回标准错误码(-1=网络异常,-2=用户拒绝,-3=系统不支持);③ 不使用async/await(微信基础库2.20.0以下不支持);④ 在wx.login回调里获取code,再用code换token”。这次返回的代码,我只改了2处:把wx.getUserProfile换成wx.getUserInfo(因基础库版本限制),把错误码映射表补充完整。
关键差异在于:我把平台约束、兼容性要求、技术栈限制这些“非功能需求”,全部前置为提问条件。Codex本质是个概率模型,给的约束越具体,采样空间越小,输出越可靠。就像告诉装修师傅“厨房要装洗碗机,但橱柜深度只有55cm”,比说“厨房要现代化”有用得多。
3.2 结果验证:三步交叉验证法
Codex返回代码后,我绝不直接复制粘贴。执行严格验证流程:
- 静态检查:用Cursor内置的TypeScript检查器扫描,重点看
any类型、未声明变量、潜在空指针; - 动态沙盒:在微信开发者工具里新建一个空白页面,把代码粘贴进去,只调用核心函数,观察控制台是否报错;
- 真机快照:用iPhone录屏,打开vConsole,执行相同操作,对比两段日志里
wx.getSystemInfoSync()返回的SDKVersion和version字段是否一致。
曾有一次,Codex生成的代码在模拟器里wx.getNetworkType返回wifi,真机却返回unknown。查文档发现,这是微信iOS端的已知Bug,必须用wx.onNetworkStatusChange监听动态变化。这个结论,是我在第三步验证时,对比真机日志里的networkType字段变化规律才确认的。
3.3 上下文管理:用Cursor的Project Context锁定知识边界
Cursor的Project Context功能常被忽略。我做了三件事:
- 在项目根目录建
.cursorignore,排除node_modules/、build/、logs/等无关目录,让Codex只读取src/和game.json; - 在
src/utils/auth.js顶部添加注释块,明确写入:“本项目微信基础库最低版本:2.20.0,禁用API:wx.cloud、wx.getConnectedWifi”; - 对每个新文件,用
Cmd+Shift+P→ “Cursor: Set Project Context”命令,手动指定该文件关联的上下文(如auth.js关联wechat-official-docs-v2.20.0)。
这样做的效果是:当我问“如何处理登录态过期”,Codex不会推荐wx.checkSession(该API在2.20.0不可用),而是给出wx.getStorage读取本地token+服务端校验的方案。它真正成了“懂我项目的同事”,而不是“通用编程助手”。
4. 微信小游戏技术栈避坑清单:来自20天踩坑的硬核总结
基于真实项目,整理出微信小游戏开发中最易踩、最难查的12个坑,每个都附带定位方法和修复代码。这些不是文档里写的“注意事项”,而是真机日志里爬出来的血泪教训。
4.1 Canvas抗锯齿失效:iOS真机文字毛边的终极解法
现象:Canvas绘制的文字在iPhone上严重锯齿,ctx.imageSmoothingQuality = 'high'无效。
根因:微信iOS端Canvas的devicePixelRatio计算异常,导致绘制分辨率错乱。
定位方法:在真机vConsole里执行console.log(wx.getSystemInfoSync().pixelRatio, window.devicePixelRatio),会发现前者是3,后者是1。
修复代码:
// 在Canvas初始化时 const query = wx.createSelectorQuery(); query.select('#myCanvas').boundingClientRect(); query.exec((res) => { const canvas = res[0]; const dpr = wx.getSystemInfoSync().pixelRatio; const width = canvas.width * dpr; const height = canvas.height * dpr; // 设置Canvas实际宽高 canvas.width = width; canvas.height = height; // 设置CSS宽高(保持显示尺寸) canvas.style.width = `${canvas.width / dpr}px`; canvas.style.height = `${canvas.height / dpr}px`; const ctx = canvas.getContext('2d'); ctx.scale(dpr, dpr); // 缩放坐标系 });提示:这个修复必须在
wx.createSelectorQuery回调里执行,不能在onLoad里直接写,因为Canvas DOM节点此时还未挂载。
4.2 WebGL模板冲突:团结引擎打包失败的根源
热搜词里高频出现“团结引擎打包微信小游戏时如何正确配置webgl模板”。我用Unity打包时也遇到同样问题:导出WebGL后,微信开发者工具报错TypeError: Cannot read property 'getContext' of null。
根因:团结引擎默认模板的index.html里,Canvas ID是gameCanvas,但微信小游戏要求Canvas ID必须是canvas,且必须在<body>第一层子元素。
修复步骤:
- 打开
Build/WebGLTemplate/Source/index.html; - 将
<canvas id="gameCanvas">改为<canvas id="canvas">; - 删除所有
<script>标签外的HTML内容(微信只认Canvas,其他DOM会被忽略); - 在
<canvas>标签后,紧跟着插入微信必需的JS:
<script type="text/javascript"> // 微信小游戏必需的初始化脚本 var canvas = document.getElementById('canvas'); if (canvas) { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } </script>4.3 本地存储容量陷阱:wx.setStorage静默失败的真相
现象:调用wx.setStorage({key:'score', data:100})后,wx.getStorage返回undefined,控制台无报错。
根因:微信小游戏本地存储上限是10MB,但单个key的value不能超过1MB。我的游戏存了一个Base64编码的截图,大小980KB,刚好卡在临界点。
定位方法:在vConsole里执行wx.getStorageInfoSync(),查看currentSize和limitSize,再用JSON.stringify(data).length估算value大小。
修复方案:对大于500KB的数据,改用wx.setStorageSync分片存储:
function setLargeData(key, data) { const str = JSON.stringify(data); const chunkSize = 400 * 1024; // 400KB每片 const chunks = []; for (let i = 0; i < str.length; i += chunkSize) { chunks.push(str.substring(i, i + chunkSize)); } // 存储分片数 wx.setStorageSync(`${key}_chunks`, chunks.length); // 存储每一片 chunks.forEach((chunk, index) => { wx.setStorageSync(`${key}_chunk_${index}`, chunk); }); }4.4 网络请求超时:wx.request在弱网下的真实表现
微信文档写超时默认60秒,但实测在2G网络下,timeout设为60000毫秒,请求仍会在12秒左右中断。
根因:微信客户端有自己的网络层超时策略,timeout参数只影响JS层等待,底层TCP连接由微信SDK控制。
解决方案:实现指数退避重试
async function requestWithRetry(url, options = {}, maxRetries = 3) { for (let i = 0; i <= maxRetries; i++) { try { const res = await wx.request({ url, ...options, timeout: 15000 // 强制设为15秒 }); return res; } catch (err) { if (i === maxRetries) throw err; // 指数退避:1s, 2s, 4s await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000)); } } }4.5 分包加载失败:wx.loadSubNVue找不到页面的排查链
现象:wx.loadSubNVue({url: '/sub/pages/game/game.nvue'})报错page not found。
排查链:
- 检查路径:微信小游戏不支持
.nvue后缀,必须是.js(Unity导出的是.js,团结引擎导出的是.nvue,需手动改后缀); - 检查分包配置:
game.json里subNVue字段必须存在,且subNVue数组包含该页面ID; - 检查文件位置:分包JS文件必须放在
subNVue/目录下,不能放在pages/; - 检查编译:微信开发者工具需勾选“启用分包加载”,且重启工具生效。
4.6 用户授权拒绝:wx.authorize回调不触发的隐藏条件
现象:调用wx.authorize({scope: 'scope.userInfo'})后,用户点“拒绝”,但回调函数不执行。
根因:微信要求wx.authorize必须由用户手势触发(如bindtap),如果在onLoad里直接调用,iOS端会静默失败。
修复:所有授权调用必须包裹在用户事件里
<!-- WXML --> <button bindtap="handleAuth">获取用户信息</button>// JS handleAuth() { wx.authorize({ scope: 'scope.userInfo', success: () => { /* 成功逻辑 */ }, fail: () => { /* 拒绝逻辑 */ } }); }4.7 音频播放失败:wx.createInnerAudioContext的iOS黑盒
现象:音频在模拟器能播,iOS真机静音。
根因:iOS端wx.createInnerAudioContext必须在用户首次触摸后创建,且需调用audioCtx.autoplay = true。
修复:
let audioCtx = null; // 在用户首次触摸时初始化 wx.onTouchStart(() => { if (!audioCtx) { audioCtx = wx.createInnerAudioContext(); audioCtx.autoplay = true; } }); // 播放前检查 function playSound(src) { if (!audioCtx) { console.warn('Audio context not initialized'); return; } audioCtx.src = src; audioCtx.play(); }4.8 自定义组件通信:this.triggerEvent在分包里的作用域陷阱
现象:自定义组件<my-button>触发事件,在分包页面里监听不到。
根因:微信小游戏分包页面的this指向分包实例,而自定义组件的triggerEvent默认向当前页面广播,分包页面无法捕获。
修复:在自定义组件JS里,显式指定事件目标
// my-button.js methods: { handleClick() { // 向父页面发送事件 this.triggerEvent('click', {data: 'from-button'}); // 同时向分包页面发送(关键) const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; if (currentPage && currentPage.triggerEvent) { currentPage.triggerEvent('button-click', {data: 'from-button'}); } } }4.9 Canvas像素丢失:wx.canvasToTempFilePath返回空字符串的机型特例
现象:华为Mate50 Pro上,wx.canvasToTempFilePath返回{tempFilePath: ''}。
根因:该机型微信客户端对Canvas的toDataURL实现有缺陷,需强制转为Blob再转URL。
修复:
async function canvasToTempFile(canvasId) { try { const res = await wx.canvasToTempFilePath({ canvasId, fileType: 'png' }); if (!res.tempFilePath) { // 降级方案:用Canvas.toDataURL + Blob const canvas = wx.createCanvas(); const ctx = canvas.getContext('2d'); // 此处需重新绘制Canvas内容... const dataUrl = canvas.toDataURL('image/png'); const blob = await fetch(dataUrl).then(r => r.blob()); const file = new File([blob], 'share.png', {type: 'image/png'}); return { tempFilePath: URL.createObjectURL(file) }; } return res; } catch (err) { console.error('Canvas to temp file failed:', err); } }4.10 实时日志丢失:wx.getRealtimeLogManager的采样率陷阱
现象:开启实时日志后,只收到10%的日志。
根因:微信默认采样率是10%,需手动设为100%。
修复:在app.js里
const log = wx.getRealtimeLogManager({ level: 3 }); log.setFilterMsg(''); // 清空过滤 log.setSampling(100); // 设为100%4.11 分包体积超标:subNVue包体超过2MB的压缩方案
现象:分包subNVue/目录超过2MB,上传失败。
根因:微信对分包体积有硬性限制,且不计算CDN压缩。
解决方案:
- 删除所有未使用的图片资源,用
wx.loadSubNVue按需加载; - JS代码启用UglifyJS压缩(微信开发者工具自带);
- 对大JSON数据,改用二进制ArrayBuffer存储,体积减少40%;
- 最狠一招:把分包JS文件用
wx.downloadFile动态下载,存入wx.getFileSystemManager().writeFile,绕过分包体积限制。
4.12 审核驳回话术:如何用技术语言说服审核员
当审核驳回理由是“玩法同质化”时,不要争辩“我们不一样”,而是提供技术证据:
- 附上
game.json的description字段截图,证明语义重构; - 提供
src/logic/目录下核心算法文件的代码行数统计(如“消除逻辑”仅12行,而“区域校准逻辑”达217行); - 用
git diff生成关卡数据文件对比,证明所有关卡布局为手工设计,非算法生成。
5. 20天时间线还原:每天做什么,为什么这么做
把20天拆解成可复用的时间单元,不是按“第1天学Cursor”,而是按“第1天解决什么问题”。这才是真实项目节奏。
5.1 第1-3天:建立可验证的最小闭环
目标:让“Hello World”能在真机上运行,且能被监控。
行动:
- Day1:安装Cursor,配置Codex(用官方CLI,避开代理问题),创建空微信小游戏项目;
- Day2:写第一个Canvas绘制逻辑,用
wx.createSelectorQuery获取Canvas,确保真机vConsole能看到绘制结果; - Day3:接入
wx.getRealtimeLogManager,配置100%采样率,验证日志能实时上报到腾讯云。
为什么:不追求功能,只追求“可观测性”。如果连日志都收不到,后面所有优化都是空中楼阁。
5.2 第4-7天:确定技术栈生死线
目标:找出微信小游戏的绝对禁忌,划出开发红线。
行动:
- Day4:测试React/Vue/Svelte可行性,确认全部失败,选定Canvas+DOM混合方案;
- Day5:压测本地存储,确认单key 1MB限制,设计分片存储方案;
- Day6:真机测试所有音频API,确认
wx.createInnerAudioContext的iOS限制; - Day7:打包测试,确认WebGL模板修改点,建立Unity导出标准流程。
为什么:这四天决定项目生死。如果选错技术栈,后面16天全是返工。
5.3 第8-12天:核心玩法MVP开发
目标:用最少代码实现可玩的核心循环。
行动:
- Day8:用Canvas绘制游戏主界面,实现触摸拖拽逻辑;
- Day9:接入微信登录,实现token持久化,设计离线模式;
- Day10:实现关卡数据加载,用JSON配置关卡,避免硬编码;
- Day11:添加音效反馈,用Web Audio API生成合成音;
- Day12:完成首关,进行真机压力测试(连续玩30分钟,监控内存泄漏)。
为什么:MVP不是“能跑就行”,而是“能暴露所有核心问题”。首关必须包含登录、存储、渲染、音效、网络(如分享),否则问题会堆积到后期。
5.4 第13-15天:合规与审核攻坚
目标:让代码符合微信审核规则,且能解释清楚。
行动:
- Day13:重写所有UI文案,替换“消除”“通关”等敏感词;
- Day14:准备《玩法差异对比表》,录制真机演示视频;
- Day15:提交审核,同步搭建监控告警,准备应对驳回。
为什么:审核不是技术问题,是沟通问题。提前准备好技术证据,比临时解释高效十倍。
5.5 第16-20天:上线与防御性迭代
目标:让上线后的问题可定位、可修复。
行动:
- Day16:上线灰度,5%用户,监控错误率;
- Day17:根据真机日志修复华为机型Canvas问题;
- Day18:优化分包加载,首屏时间从1.2秒降到0.6秒;
- Day19:添加用户反馈入口,收集体验问题;
- Day20:发布正式版,同步更新GitHub文档,写这篇复盘。
为什么:上线不是终点,而是观测起点。真正的开发,从用户真实环境开始。
6. 关于Cursor和Codex的冷思考:工具永远在进化,人必须更清醒
最后想说点扎心的:这20天里,我花最多时间的,不是写代码,而是理解微信小游戏这个平台的脾气。Codex能告诉我wx.request的参数怎么写,但它不会告诉我,为什么在iOS微信8.0.50里,wx.getNetworkType会返回unknown;Cursor能高亮语法错误,但它不会提醒我,wx.setStorageSync在存储大对象时,实际占用的磁盘空间是JSON.stringify(obj).length * 1.3。
工具链的价值,从来不是替代人的判断,而是把人从“查文档-试错-再查”这种低熵劳动里解放出来,让人专注在更高维的问题上:比如,当用户在第3关卡住时,是关卡设计太难,还是提示文案不够清晰?当分享率低于5%时,是按钮位置问题,还是激励机制没到位?
我现在的Cursor配置里,有一个永久置顶的笔记,标题叫《微信小游戏已知缺陷清单》,里面记着:
- iOS端Canvas抗锯齿失效(已修复)
- 华为Mate50 Pro Canvas转图失败(降级方案)
- 微信8.0.50网络类型识别异常(改用
wx.onNetworkStatusChange)
这个清单,比任何Codex提示词都重要。因为它不是AI生成的,而是我亲手在真机上一行行验证出来的。它提醒我:所有工具的终点,都是让人更接近真实世界,而不是更远离它。
如果你正打算用类似工具做微信小游戏,我的建议只有一条:第一天,别急着写代码。先买一台iPhone、一台华为、一台小米,连上vConsole,把微信开发者工具的“真机调试”功能调通。然后,对着文档,把每一个API在三台机器上各跑三遍。这个过程枯燥、缓慢、甚至有点笨,但它会让你在第20天上线时,心里有底。