Living Museum of Learning

Where real moments become exhibits
← Prev Next →
Red Kills Red

Red Kills Red

A Golden Army bug that taught the host not to trust the guest

Situation

Golden Junqi was finally playing over the Internet.

Two iPads joined the same game room.
Deployment finished.
Red moved first.

Everything looked normal.

Then I saw something that should never happen in Junqi:

Red killed Red.

I had screenshots.

A red Major stood at (3, 7).
Another red Captain stood at (4, 7).

Red moved onto Red.

And the Captain disappeared.

😂

Turning Point

At first, the game rules looked innocent.

isValid() already contained exactly the rule we wanted:

if target.player == movingPiece.player
return false

So how could Red possibly kill Red?

The answer was not in the Junqi rules.

It was in the network.

Emergence

The local player and the remote player were taking two completely different paths.

The local player went through:

tap
↓
updateMoveLocally()
↓
isValid()
↓
movePiece()

So an illegal move was rejected.

But a guest player's move went through:

tap
↓
sendMoveAttempt()
↓
Internet
↓
receivedMove()
↓
applyMove()
↓
movePiece()

And applyMove() simply trusted the incoming move.

It never asked:

"Is this move legal?"

It just executed it.

The bug was not:

Red can kill Red.

The bug was:

The host trusted the guest.

Learning

This was a small Junqi bug with a very large programming lesson.

A program has boundaries.

Inside the boundary, we may know that data has already been checked.

Outside the boundary, we cannot assume anything.

An Internet message is an attempt, not a fact.

So the host became the authority:

Guest: "I want to make this move."

Host: "Let me check."

Host:
legal → apply
illegal → reject

Now every incoming move passes through the same rules before changing the game state.

The funny screenshot shows a red piece killing another red piece.

The real exhibit is about trust boundaries.

Theme

Never trust input from outside your boundary.

A game can teach networking.

A bug can teach architecture.

And sometimes the best debugger is simply a red piece murdering its own teammate. 😂

What Is Possible?

A tiny board-game bug can reveal a fundamental principle of networked software.

How Does It Happen?

Different execution paths accidentally gave local moves and remote moves different levels of validation.

Why Does It Matter?

Because the same mistake appears far beyond games: whenever software accepts data from another device, process, user, or system, validation belongs at the boundary where trust ends.