开发者
What MasterMemory Solves—and What It Doesn't: A Practical Guide to Static Game Data in Unity
Introduction When you build games with Unity, you eventually run into the problem of managing static game data—often called master data in Japanese game development. At first, ScriptableObject may be more than enough. If your project has a few dozen items, a few dozen enemies, and only a small number of stage definitions, ScriptableObject is convenient because you can inspect and edit everything directly in the Unity Editor. As the project grows, however, the situation changes. You may end up with tables for items, characters, skills, quests, rewards, shops, gacha pools, stages, enemy placements, progression curves, and localization text. The data is no longer edited only by programmers. Planners and game designers may need to work with it in Excel or Google Sheets. At that point, the problem is no longer just choosing a file format. You need to think about questions such as: How do you load a large amount of data quickly? How do you write ID lookups and composite-key queries safely? Should CSV or JSON be parsed directly at runtime? Is it reasonable to create a large number of Dictionaries? How do you validate references between tables? How do you debug data after converting it to binary? How do you connect the source data edited by planners to the data loaded by Unity? For the runtime loading and lookup part of that problem, one strong option is Cysharp's MasterMemory . The official README describes MasterMemory as a “Source Generator based Embedded Typed Readonly In-Memory Document Database” for .NET and Unity. In practical terms, you define your schema as C# types, a Source Generator creates a typed read-only in-memory database API, and the application loads MessagePack binary data that can be queried through type-safe methods. The official README highlights performance compared with SQLite, low allocation during queries, a small database size, and generated database structures that are type-safe and IDE-friendly. Cygames Engineers' Blog also has useful articles
AI 资讯
Quantos gamedev são necessários para trocar uma lâmpada?
SPOILER: De 1 à 2000 Durante minha jornada como jogador , existiu uma coisa que me despertou muita curiosidade: os créditos. Quando eu jogava coisas como Final Fantasy, ficava completamente arrepiado quando via aquelas cenas antes do menu inicial, com CGIs bem bonitões e um monte de nomes em japonês — muitos deles que, honestamente, até hoje não sei quem são. Esse arrepio também acontecia quando eu chegava ao final de algum jogo e começavam a aparecer nomes e mais nomes. Quando eu entendi o que eram aqueles nomes, a primeira coisa que me veio à mente foi: peraí, precisa de tudo isso de gente pra fazer um jogo? Too long, didn't read : Sim e não. Skyrim levou aproximadamente 6 anos com uma equipe de 100 pessoas (e ainda é dito que é uma equipe enxuta), enquanto Stardew Valley levou 4,5 anos com uma "equipe" de apenas 1 pessoa. Eles têm quase o mesmo tamanho em horas jogadas na campanha principal. Not too long, I'll read it : É um pensamento lógico que trabalhos maiores no mundo da tecnologia envolvam uma quantidade maior de pessoas trabalhando E tempo. Dessa forma, seria correto assumir que um trabalho menor exige menos tempo e menos pessoas trabalhando. Mas o que os dados dizem? King of Fighters 94: 2 anos, começou com 6 pessoas, aumentou para 60. Clair Obscure - Expedition 33: aproximadamente 6 anos, 30 pessoas. TES V - Skyrim: 6 anos, 100 pessoas. Super Mario Bros: 2 anos, 7 pessoas na equipe principal. Stardew Valley: 4,5 anos, 1 pessoa. Kenshi: 12 anos, 1 pessoa por 6 anos (trabalhando meio período), aproximadamente 8 pessoas por mais 6 anos (tempo integral). Final Fantasy VII (PS1): aproximadamente 2 anos, de 100 a 150 pessoas (uma das maiores equipes da indústria na época). Final Fantasy VII Remake: Cerca de 5 anos, e não se tem números exatos, mas os créditos citam mais de 2000 pessoas, incluindo muitos -istas e -ores (vou tentar confirmar esse número depois). É claro que existem muitos fatores envolvidos aí, como época, demandas de mercado, prazos, tecnologia
开发者
VistralNova Product Improvement and EVM-to-PVM
VistralNova began by developing Web3 gaming experiences and is now expanding toward developer...
AI 资讯
LED Strip Tetris: Zero-Code Hardware Game with TuyaOpen + Claude Code Tutorial
I built an LED Strip Tetris game — without writing a single line of code. No keyboard mashing. No debugging at 2 AM. No reading 500 pages of datasheets. Just natural language prompts, an AI agent, and a Tuya T5 AI Core board. Here's the full breakdown of how it works 👇 🧩 What Is LED Strip Tetris? LED Strip Tetris is a DIY hardware game built entirely through natural language prompts using TuyaOpen IDE and Claude Code. It runs on a Tuya T5 AI Core development board with a WS2812 LED strip (72 LEDs) and three color-matched buttons — red, green, and blue. Colored LEDs fall from the top of the strip; players press the matching button to shoot a colored LED upward and eliminate the falling one on contact. The entire game — firmware, game logic, hardware wiring, sound effects, compilation, and flashing — was generated by AI. Zero manual coding. 🔌 The Hardware (Ridiculously Simple) Component Role Tuya T5 AI Core Board Main MCU — runs game logic, drives LED strip and buttons WS2812 LED Strip (72 LEDs) Display — colored LEDs fall and get eliminated 3 Push Buttons (Red / Green / Blue) Input — shoot matching color upward to clear falling LEDs Speaker Sound effects on button press That's it. No custom PCB. No complex wiring harness. Just four components plugged into a dev board. 🤔 Why This Is a Big Deal Here's what building a hardware game normally looks like: Step Traditional Approach Vibe Coding with TuyaOpen IDE Dev environment setup Install toolchain, configure SDK, fight dependencies Copy a workflow link, paste into Claude Code, click confirm Game logic Write C code from scratch, design state machines Describe the game in one sentence, AI generates the code Hardware config Read datasheets, look up GPIO mappings, manually configure Tell AI which pins you're using, it handles the rest Sound effects Write audio decoding code, integrate codecs Give AI the file path, it decodes and compiles Debugging Serial logs, oscilloscope, hours of trial and error AI self-diagnoses compile
开发者
Congrats to the June Solstice Game Jam Winners!
We are so excited to announce the winners of the June Solstice Game Jam, our celebration of the...
AI 资讯
10 Common Unity Networking Issues (and How to Fix Them)
Multiplayer bugs in Unity rarely look like networking bugs. They look like "the game froze," "the player teleported," or "it worked in the Editor and broke in the WebGL build." By the time you've traced it back to the actual cause, you've usually burned an afternoon. Here are 10 issues that show up constantly in Unity networking code — WebSocket-based, Socket.IO, or otherwise — with the actual root cause and the fix. A few of these come straight out of real regression tests and commit history in socketio-unity , an MIT-licensed Socket.IO v4 client for Unity. The rest are patterns you'll recognize if you've shipped a multiplayer game. 1. Reconnect wipes your room/namespace state Symptom: Connection drops for two seconds, comes back, and the player is no longer in their room/lobby/channel — even though the server never removed them. Cause: A common (bad) reconnect implementation tears down the whole client and rebuilds it from scratch — including the list of channels/namespaces the player had joined. The reconnect "succeeds" at the transport level but silently drops application-level state. Fix: Reconnect logic should preserve subscriptions across the transport reset and only re-emit join / connect for namespaces the client already had open. If you're rebuilding the socket object on every reconnect attempt, stop — reconnect the transport, keep the namespace map. // Wrong: rebuilds everything, loses namespace state void OnReconnect () => CreateFreshEngine (); // Right: reuses the existing namespace map void OnReconnect () => ReconnectEngine (); // _namespaces untouched 2. "get_gameObject can only be called from the main thread" Symptom: Random UnityException thrown from inside a network event handler, but only sometimes — usually right when the server sends something. Cause: Your WebSocket/network library delivers callbacks on its own I/O thread. Any Unity API call ( transform.position = , Instantiate , even some Debug.Log paths) from that thread throws. Fix: Never tou
AI 资讯
I Built a Free Browser Gaming Platform – FizGame
🎮 I Built a Free Browser Gaming Platform – FizGame Over the past few weeks, I've been working on a side project called FizGame, a free browser gaming platform where anyone can instantly play HTML5 games without downloads or installations. 🌐 Website: FizGame Why I Built It I wanted to create a simple platform where players can: 🎮 Play instantly in their browser 🚫 No downloads or installations 📱 Play on both desktop and mobile ⚡ Fast loading experience Current Features Hundreds of HTML5 games Mobile-friendly design Instant game loading Categories like Puzzle, Action, Arcade, Racing, and Casual Search and game discovery Responsive UI Tech Stack PHP Symfony MySQL HTML5 Games JavaScript CSS Nginx Current Focus I'm currently working on: Better SEO Faster page speed AI-generated game descriptions Improved game recommendations Daily game publishing Social media automation Biggest Challenge One of the hardest parts isn't building the website—it's helping people discover it. I'm experimenting with: YouTube Shorts Instagram Reels Facebook Reels Pinterest Organic SEO If you've built a gaming website before, I'd love to hear what worked best for you. Feedback Welcome I'd appreciate any feedback on: UI/UX Performance Navigation SEO Features you'd like to see 🎮 Check it out: FizGame Thanks for reading! 🚀
AI 资讯
Why I removed the tier list from my Honor of Kings Global build site
I have been building a small Honor of Kings Global site called HOKMeta: https://hokmeta.com/heroes/ At first, I built it like many game sites: hero pages, counters, tools, and a tier list. But after working on the site for a while, I removed the tier list as a main page. The reason is simple: a tier list looks useful, but it does not always match how players actually choose heroes. A Marco Polo player will still play Marco Polo even if people say he is weak. A Hou Yi player usually does not search for “is Hou Yi S tier?” first. They search for things like: Hou Yi build Hou Yi arcana Hou Yi counter what to build against tanks what to change against assassins best build for ranked That made me rethink the site structure. Instead of making the tier list the center of the site, I moved the focus toward: hero build pages counter pages item pages damage calculator build compare counter picker For a small SEO site, this feels more useful too. A tier list is one page. Hero builds and matchup questions create many real long-tail pages. For example, “Hou Yi build 2026” is a clearer search intent than just “Honor of Kings tier list”. The current direction is: hero page -> build, arcana, counters, FAQ counter page -> who beats this hero and why tool page -> test builds instead of guessing item page -> understand what the item actually does It is still early, and the data is still being cleaned up, but this direction feels closer to what players need before a ranked match. If you build content/tool sites, this was a useful lesson for me: Do not blindly copy the obvious page type. Look at what users are really trying to decide.
AI 资讯
Vegas Amnesia: I turned Cognee's memory lifecycle into a detective game
Built for the WeMakeDevs × Cognee "The Hangover Part AI" hackathon — Cognee Cloud track. ▶ Play it free: vegas-amnesia.vercel.app · ⭐ Code on GitHub The problem with most memory demos When you give a developer a memory API, the demo almost always looks the same: add() some documents, search() over them, print the answer. Two functions. It works, it's fine, and it teaches you almost nothing about why graph-based memory is different from stuffing everything into a context window. Cognee actually has a four-stage lifecycle — remember → recall → memify → forget — and the interesting parts are the two everyone skips. memify consolidates what you know into new inferences. forget lets you delete a belief and watch the graph heal around it. Memory you can reason over and correct . So instead of writing another RAG demo, I asked: what if the memory lifecycle wasn't the plumbing — what if it was the game ? Meet HAL-9001 You play HAL-9001 , a personal AI assistant (yes, HAL 9000's slightly more helpful successor). Your owner Dev had a wild night in Vegas. At 6 AM your memory graph was corrupted. His fiancée Priya lands at noon, there's a suspicious ring on his finger, and you remember nothing . The screen boots to a "MEMORY CORRUPTED" terminal and an empty graph. Your job: reconstruct the night, catch the lies, and answer the final question — what happened, and where's the ring? — before noon. Every location you explore, every clue you examine, every witness you interrogate feeds a live 3D memory graph that you can pop open at any time. That graph isn't a visualization of the game state. It is the game state — it's your Cognee dataset, rendered. The four mechanics = the four lifecycle ops Here's the mapping I'm most proud of. Each Cognee operation is a verb the player performs: You do this in-game Cognee Cloud call What happens 🗂 File It on a clue POST /api/v1/remember The fact is ingested + auto-cognified into graph nodes that pop into view ❓ Ask HAL a question POST /api/v1/r
AI 资讯
LINQ and ZLinq in the Unity 6 Era: Avoiding GC Allocations in Large-Scale Projects
Introduction In large-scale Unity development, GC Alloc can quietly become a real problem. At first, nothing looks wrong. But as the project grows and you add more enemies, UI, master data, events, states, notifications, logs, and other systems, small allocations that happen every frame begin to pile up. LINQ is especially convenient. var aliveEnemies = enemies . Where ( x => x . IsAlive ) . OrderBy ( x => x . DistanceToPlayer ) . ToList (); It is readable. But if this kind of code runs every frame, it can become a source of both GC Alloc and CPU overhead. Unity's official documentation also recommends reducing frequent managed heap allocations as much as possible, ideally getting close to 0 bytes per frame. https://docs.unity3d.com/2022.3/Documentation/Manual/performance-garbage-collection-best-practices.html For general GC Alloc best practices, this article refers to the Unity 2022.3 documentation, because the general guidance still applies. Unity 6-specific GC behavior is covered later using the Unity 6.0 documentation. This article assumes Unity 6.0 as the minimum Unity version and explains how to choose between regular LINQ and ZLinq in production code. Unity 6.0 uses the Roslyn C# compiler, and its C# language version is C# 9.0. However, some C# 9 features, such as init-only setters, are not supported. https://docs.unity3d.com/6000.0/Documentation/Manual/csharp-compiler.html The short version The point of this article is not to ban LINQ completely. Do not use LINQ in hot paths just because it is readable. Do not assume ZLinq solves everything just because you introduced it. Those are the two main ideas. A rough guideline looks like this: Area Guideline Editor extensions, build scripts, debug code Regular LINQ is usually fine Startup, loading, initialization LINQ can be fine, but measure when data size is large Update / LateUpdate / FixedUpdate Avoid LINQ by default Code that is not per-frame but still called frequently Consider ZLinq Code that materializes res
AI 资讯
I Launched an AI-Built Board Game — Here's What Happened Next
Not long ago I wrote about how I built a browser-based board game called "Growing City" in three days using AI — and how the hardest part wasn't the code at all. Some time has passed, and I wanted to share what happened next. Layout Bugs While vibe-coding solo, I only tested on my own screen, resolution, and browser. The problem surfaced as soon as real users joined with different setups: some people saw everything misaligned, some things got clipped, some cards overlapped each other. This is how it looked on some screens I had to rewrite the layout to use adaptive sizing so the game looks correct regardless of screen resolution. It should work now — but if something still looks off on your end, let me know and I'll fix it. Bots Started Talking Another change, unrelated to bugs. The service started feeling more alive. Previously, bots just played: rolled dice, bought cards, said nothing. Now they react in the chat to what's happening in the game — if someone's building gets taken, if someone buys an expensive card or runs out of money. It's a small thing, but the game feels noticeably more lively. An empty game with silent bots versus a session where someone's commenting on what's happening in chat — it's a meaningfully different experience, even though the game itself is the same. Thank You to Early Players A special thanks to everyone who tried the game after my first article. And extra thanks to a user with the nickname SHAM, who pointed out that the game rules never said you can't buy multiple purple cards in a row — even though the game itself has that restriction. Fixed! What's Next The project is still going. I'm thinking about ads and other ways to bring in players. Without new users, it's hard to get feedback — and without feedback, it's hard to know what to fix or improve first. The unit economics don't quite work out yet: paid acquisition costs more than I'm willing to invest at this stage. I'll keep figuring it out. If you have ideas on how to find playe
AI 资讯
I Built a Board Game in 3 Days with AI — and Realized Code Was the Easiest Part
I love board games — especially the kind you can play without leaving home. You just call your friends, drop a link, and you're playing in minutes. At some point, I caught myself wondering: how realistic is it to build a complete game almost entirely with AI? Not a prototype, but something actually playable. I decided to find out. Three days later, I had a working browser-based board game: rooms, multiplayer, bots, chat, full game sessions. But the most interesting thing turned out to have nothing to do with AI writing code. What's the Game? The game is called "Growing City" (Растущий город). It's an economic board game about developing your own city. Each turn, players roll a die, buildings activate, income flows in, and you earn money to buy new structures. Gradually you build up enterprises, construct your economic engine, and race to complete all the key buildings before your opponents. You can play directly in the browser with no registration. I wanted the simplest possible entry: open the site, enter a nickname, create or join a room. If the mechanics seem familiar — you're not imagining it. I was inspired by a well-known city-building board game. Day 1: AI Really Can Write Games I'm not a developer. I work in tech, but I don't code professionally. Over the past few months I've been experimenting heavily with vibe coding, so I decided to build this project the same way. I didn't start with code at all. First, I wrote out the mechanics in detail: what cards exist, how a turn plays out, what should happen in each situation. Once the logic settled, I started gradually converting the description into code using AI. Day 2: Writing the Game Was Just the Beginning When the first playable version appeared, it quickly became clear that the code was far from the hardest part. The biggest problem was balance . If you leave everything as-is, players find the single most profitable strategy within a few games and repeat it endlessly. I had to manually tweak card costs, adj
开发者
You're Writing Paper Commands Wrong
You've probably written a CommandExecutor before. Everyone who's touched Bukkit has. Declare the command in plugin.yml , implement onCommand , cast args[0] to whatever you need, hope nobody fat-fingers the input. It compiles. It runs. It's confusing to debug. And it's the wrong way to do it in 2026. # plugin.yml commands : punish : description : Opens the punishment GUI usage : /punish <player> public class PunishCommand implements CommandExecutor { @Override public boolean onCommand ( CommandSender sender , Command command , String label , String [] args ) { if (!( sender instanceof Player staff )) return true ; if ( args . length < 1 ) return true ; Player target = Bukkit . getPlayer ( args [ 0 ]); if ( target == null ) { sender . sendMessage ( "Player not found." ); return true ; } // ... open the GUI return true ; } } Tie it together in onEnable() with getCommand("punish").setExecutor(new PunishCommand()) , add a separate TabCompleter implementation to handle suggestions, and you're done. Seems perfectly fine... totally not confusing at all... (if you understood any of that, you're doing better than I am :P) This implementation has many issues... like Bukkit.getPlayer(args[0]) only matching an exact, currently-online name. No selectors. No partial matching. You write all of that yourself or not at all. Tab completion lives in a second method you keep in sync with parsing by hand. Change one, forget the other, and tab completion starts "lying" to your players (a problem that has taken me HOURS to solve in the past... i'm getting flashbacks ;-;). And the tree itself is static, fixed in plugin.yml . Want /report to take a severity argument only when severities are configured? You can't say that in plugin.yml and you end up with a tangled mess that is almost never clean (either to you, or the players). Paper ships Mojang's Brigadier (the same framework vanilla Minecraft uses for everything) through a lifecycle hook: LifecycleEvents.COMMANDS . You register a tree of
开发者
How I Built a Zero-Friction Browser Gaming Platform (Zero Sign-Ups, Zero Downloads)
I built GameDeck — a gaming platform where you pick a badge, type a name, and play. That's it. No accounts, no launcher downloads, no tracking. Here's how I built it and what I learned. The stack Frontend : Pure browser-based, vanilla JS Deployment : Google Cloud Run i18n : 3 languages (EN, 简体中文, 繁體中文) with instant switching Identity : Emoji badge system — no usernames, no passwords The architecture The entire app is a single-page browser app. No backend for user auth (because there is no auth). Sessions are ephemeral — nothing is stored. Multi-language i18n Adding 3 languages was the #1 feature request within 24 hours of launch. Simple key-value translation maps, no framework needed. The badge identity system Instead of usernames, users pick an emoji badge (🎮 ⚡ 🦊 🐉 🐼 🚀 🐱 🐯 🌟 🍿). This turned out to be the most talked-about feature. It's fun, zero-friction, and surprisingly expressive. Privacy by default No data collected. No cookies. No analytics. Just the game. Privacy isn't a feature — it's the absence of features that invade privacy. What I'd do differently Multi-language from day 1 More game variety before launch Better mobile responsiveness Try it : https://gamedeck-804028808308.us-west2.run.app Source : Built solo, open to questions! Would love feedback from the dev community — especially on the browser game architecture and i18n approach.
AI 资讯
Play today’s game from Issue #2 of The Daily Context!
Yesterday, we kicked off our physical newspaper, The Daily Context, at the AI Engineer World’s Fair...
开发者
The grammar of what's possible
There's a Yu-Gi-Oh game on PS1 where you can fuse two cards together. The result isn't random. There are rules. But you don't know the rules yet — you just know that two inputs produce a third thing that neither input was, and that the third thing surprises you even when it shouldn't. That's the hook. Not the surprise alone. The realization underneath the surprise that the system has depth. That there's a grammar to what's possible, and you can learn it. I've been building toward that feeling ever since. Jade Cocoon does the same thing with monsters — merge two creatures, watch the result carry both parents in its design. Dragon Quest Monsters runs on fusion too. Yu-Gi-Oh Forbidden Memories taught me that combination-as-discovery is its own mechanic, separate from any theme it wears. Everything Is Crab is the roguelike version: you absorb what you fight, you become it, you discover what you're becoming one encounter at a time. No Man's Sky showed me that procedural generation has finally caught up to what those PS1 games were reaching toward — creatures that feel like they emerged from a system rather than a designer's hand. The mechanic isn't genetics. Genetics is just the implementation I keep reaching for. What I'm actually trying to build is a machine that produces controlled emergence — outcomes that surprise you within a system deep enough to eventually master. Pure RNG is a slot machine. You can't get better at it. Pure determinism is a calculator. You can solve it and put it down. The games I keep returning to live between those poles: consistent enough to reward learning, deep enough to keep producing novelty. TurboShells was an attempt at this. Turtles whose bodies expressed their genomes at render time — shell radius, leg length, color emerging from a sequence. The faster ones bred. Over generations you watched the population drift. The system had rules. The outcomes still surprised you. SlimeGarden chose basic shapes deliberately. If the creature is simp
AI 资讯
Need a break? Play today's game from The Daily Context.
We (at DEV and MLH) are covering AI Engineer's World Fair by printing a physical newspaper called...
AI 资讯
Building AR Hide and Seek — Shipping a Solo Indie LiDAR Game to the App Store
The idea came from an extremely serious game of hide and seek with my cousins. We were adults, which made it ridiculous, but also strangely perfect. Someone was hiding behind a couch in plain sight, surviving only because the seeker did not look carefully enough. That made me wonder: what if looking carefully was not enough? What if the seeker could not freely look around the room? What if they could only see the world through their phone screen, while virtual obstacles blocked parts of their view? That became the core idea behind AR Hide and Seek: a local multiplayer hide and seek game where 2-5 players use the space they are already in. The hiders physically hide somewhere in the room, while the seeker views the environment through an iPhone. The phone fills the space with digital clutter, making familiar rooms harder to read. One phone. One seeker. Real hiding places. Virtual obstacles. Why LiDAR? LiDAR on iPhone Pro models gives the phone a real-time depth map of the environment, with centimeter-level understanding of the space around it. That means virtual objects can be placed in ways that respect real-world geometry: a crate can sit on the floor, a wall can align with an actual wall, and obstacles can feel like they belong in the room rather than floating on top of it. For a game where the virtual environment needs to feel like it genuinely fills the space, that difference matters immediately. Without reliable depth information, objects can drift, clip, or hover in ways that break the illusion. The tradeoff is device requirement. LiDAR is only available on iPhone Pro models, which narrows the audience. But for this game, the better AR experience was worth it. The seeker sees a version of the room cluttered with virtual obstacles. The hiders are still physically hiding behind real furniture; the phone does not make them disappear. It simply makes finding them harder. Designing the Core Loop The mechanic is simple on paper, but it took a surprising amount of tu
科技前沿
為什麼那個會「注意你」的展品,反而讓你更想靠近
為什麼那個會「注意你」的展品,反而讓你更想靠近 博物館互動設計的隱形槓桿 東京。 teamLab 展覽入口。 地面是一整片黑色的水面,倒映著數位花朵。 你踏進去。 花朵在你腳步周圍散開,隨著你的移動一圈一圈地綻放和飄落。 你停下來,花也停下來。 你開始走,花就跟著你。 你以為是感應。但仔細看——延遲了大概 0.3 秒。 不是「立刻反應」,是「好像在觀察你,然後才決定」。 你站在那裡又多看了三秒。 你第一個「對」 讓我問你一個問題。 你去過那種「互動博物館」嗎?牆上寫著「請觸摸」,但你碰了之後什麼都沒發生——或者是那種「語音導覽機」,你對著它說話,它說「請靠近一點」。 然後你就失去興趣了。 現在讓我想另一個場景。 一個會動的恐龍骨骼。你站在它面前的時候,它頭轉過來看了你一眼。 你知道這是感應器。你知道工程師設計了「檢測到人」的時候讓它轉頭。 但你還是覺得—— 「它在看我。」 兩種互動,哪一個讓你停留更久? 你第一個「咦」 這裡有一個秘密。 讓人停留更久的,通常不是「立刻反應」的互動。 是那種「 好像在決定要不要理你 」的互動。 為什麼? 因為「立刻反應」讓你確認了——「這是機器」。 但「好像在決定要不要理你」讓你的大腦進入了一個不確定的狀態—— 「它真的知道我來了嗎?」 「它在決定什麼?」 「我想看看它決定什麼。」 這個「我想看看」就是互動設計裡最重要的瞬間—— 參與者的好奇心,被啟動了。 玉樹真一郎在《任天堂的體驗設計》裡,分析了一個現象: 《超級馬里奧》裡,當玩家靠近一個問號磚塊,頂了它,沒有任何東西掉下來。 玩家不會覺得「這個遊戲壞了」。 玩家會想:「 為什麼這次沒有? 」 然後再頂一次。 為什麼「沒有東西掉下來」沒有讓玩家放棄? 因為設計師在玩家心裡創造了一個「 還沒發生的確定事件 」。 玩家知道「遲早會有東西掉下來」。所以他們願意等待、願意再試一次。 博物館的互動設計也應該這樣。 不是立刻給答案。是讓你相信「答案快來了」,然後讓你一直站在那裡等。 你最後「我要改變做法」 讓我說一個失敗的設計。 一個科技博物館有一面「觸控牆」。牆上有很多按鈕,碰了就會播放影片、發出聲音、變色。 一開始很多小孩去碰。 但大概十五分鐘之後,那面牆就沒人碰了。 為什麼? 因為碰了 100 次,沒有任何一次比另一次更「值得等待」。 每一次都是立刻發生,每一次都是同樣的結果。 沒有任何一件事需要「決定」。 現在讓我說一個成功的設計。 同一個博物館的另一區,有一面「情緒牆」。 你站在牆前,系統會掃描你的臉——不是真的分析情緒,而是給你一個顏色。 每個人的顏色都不太一樣。 但顏色不是立刻出現的。 大概等了兩秒——然後它慢慢浮現出來。 在這兩秒裡,每個站在牆前的人都沒有動。 他們在等。 他們相信顏色一定會出現。但他們不確定會是什麼顏色。 三個馬上可以用的方向 第一:不要立刻給回饋。 加入一個 0.3 到 2 秒的「思考時間」。 讓互動看起來像「系統在決定」,而不只是「系統在檢測」。 壞掉的燈 vs 正在決定的燈——後者讓人更想站在那裡等。 自己試試看:30 行做出「延遲反應」的燈 // p5.js — 試試延遲回饋的感覺 let lights = []; const DELAY = 12 ; // 幀數延遲(約 0.2 秒) function setup () { createCanvas ( 400 , 400 ); for ( let i = 0 ; i < 5 ; i ++ ) { lights . push ({ history : [], lit : false }); for ( let j = 0 ; j < Math . max ( DELAY , 1 ); j ++ ) lights [ i ]. history . push ( false ); } } function draw () { background ( 30 ); let hovered = floor ( mouseX / 80 ); for ( let i = 0 ; i < lights . length ; i ++ ) { lights [ i ]. history . push ( hovered === i ); if ( DELAY > 0 ) lights [ i ]. history . shift (); lights [ i ]. lit = DELAY > 0 ? lights [ i ]. history [ 0 ] : ( hovered === i ); } // 畫燈泡 noStroke (); for ( let i = 0 ; i < lights . length ; i ++ ) { fill ( lights [ i ].
开发者
ESP32 OLED Mini Shooter Game: Full Beginner Tutorial
Want to turn a small ESP32 board into a mini arcade game you can actually play? This ESP32 OLED Mini Shooter Game uses a 128x64 OLED display and two push buttons to create a simple shooter experience. The player moves left and right, bullets fire upward, and enemies fall from the top of the screen. It is a small project, but it already feels like a real handheld game once the display starts updating. This build is a great next step after basic OLED and button tutorials. Instead of only printing text or drawing one shape, the code manages several moving objects at the same time. It tracks the player, bullets, enemies, collisions, and game-over state. The screen is divided into a simple grid. The 128x64 OLED becomes a 16x8 playfield, where each tile is 8x8 pixels. This makes object movement easier to understand because the player, enemies, and bullets move by grid position instead of raw pixel math. Why build it? This project teaches interactive programming on real hardware. The ESP32 reads button input, updates game objects, checks collisions, and draws the next frame on the OLED. That is much more active than a normal sensor display project. It also teaches timing without blocking the whole game flow. The code uses millis() to control when bullets and enemies update, so they can move at different speeds. This is useful because many embedded projects need timed actions without stopping everything else. What you'll learn ESP32 OLED display control - drawing text, squares, circles, and game objects on an SSD1306 screen. Custom I2C pins - using Wire.begin(5, 19) so the OLED uses GPIO5 for SDA and GPIO19 for SCL. Button input handling - reading two push buttons for left and right movement. Debounce logic - preventing one press from being counted many times. Grid-based game design - turning a 128x64 screen into a simple 16x8 game map. Game object arrays - storing multiple bullets and enemies with active/inactive states. Timer-based updates - using millis() to move bullets