
This tutorial will take approximately 15 minutes to complete.
The message packet comprises a header followed by 24 bits (3 bytes), which can be interpreted using the following table. This structure significantly expands gameplay options by incorporating game objects such as power-ups.
Byte 0 | Byte 1 | Byte 2 | Command | Comments |
---|---|---|---|---|
0x80 | 0x01 to 0x64 | 0xE8 | Add Health | 1-100 |
0x81 | 0x01 to 0x64 | 0xE8 | Add Rounds | 1-100 |
0x82 | — | 0xE8 | RESERVED | For future expansion |
0x83 | 0x00 | Admin Kill | Removes the remainder of a player’s health | |
0x83 | 0x01 | Pause/Unpause | stops or starts the timer and all in-play actions | |
0x83 | 0x02 | Start Game | Starts a new game with the start delay active | |
0x83 | 0x03 | Restore Defaults | Resets a tagger to its default (factory) settings. | |
0x83 | 0x04 | Respawn | Respawns a dead player. Good for respawn points | |
0x83 | 0x05 | Immediate New Game | Starts a new game, ignoring the start delay | |
0x83 | 0x06 | Full Ammo | Restores a player’s ammo counter to its initial value | |
0x83 | 0x07 | End Game | Immediately ends the current game by changing the game time left down to 0. | |
0x83 | 0x08 | Reset Clock | Resets a player clock to the initial start time | |
0x83 | 0x09 | RESERVED | For future expansion | |
0x83 | 0x0A | Initialise Player | Resets the tagger | |
0x83 | 0x0B | Explode player | Causes the explosion sound effect to be played and sets health to 0. | |
0x83 | 0x0C | New game (ready) | Prepares taggers for the 0x02 start game command | |
0x83 | 0x0D | Full Health | Resets the player’s health to its initial value | |
0x83 | 0x0E | Reserved | Reserved for future expansion | |
0x83 | 0x0F | Full Armour | Resets the player’s armour to its initial value | |
0x83 | 0x10 | Red Team | Changes to red team | |
0x83 | 0x11 | Blue Team | Changes to blue team | |
0x83 | 0x12 | Yellow Team | Changes to yellow team | |
0x83 | 0x13 | Green Team | Changes to green team | |
0x83 | 0x14 | Clear Scores | Clear scores | |
0x83 | 0x15 | Test Sensors | Test IR sensor – does not change settings | |
0x83 | 0x16 | Stun Player | Player cannot shoot for a period of time | |
0x83 | 0x17 | Disarm Player | Player ammo and clips go to 0 | |
0x8A | 0x00 to 0x0F | Clips Pickup | Clips pickup from 0-15 | |
0x8B | 0x00 to 0x48 | Health Pickup | Mapped health value | |
0x8C | 0x00 to 0x0F | Flag Pickup | Flag ID 0-15 | |
0xB4 | 0x00 to 0x03 | Team Respawn | Only respawns the team selected. Good for spawn points. |
New Feature

Save the project as LaserTag_C12_Messages
Libraries, Variables, Setup() & Loop()
There is nothing to address in these steps, as they primarily involve new code without the introduction of any new libraries or hardware.
New Tab – MilesTagMessage
Create a new tab named MilesTagMessage and copy the following code into it.

void milesTagMessage(){
switch (results.value){
case 0x8300E8: Serial.println("Admin Kill"); adminKill(); break;
case 0x8301E8: Serial.println("Pause/Unpause"); pauseGame(); break;
case 0x8302E8: Serial.println("Start Game"); startGame(); break;
case 0x8303E8: Serial.println("Restore defaults"); startGame(); break;
case 0x8304E8: Serial.println("Respawn"); respawn(); break;
case 0x8305E8: Serial.println("Immediate new game"); startGame(); break;
case 0x8306E8: Serial.println("Full ammo"); fullAmmo(); break;
case 0x8307E8: Serial.println("End game"); gameOver(); break;
case 0x8308E8: Serial.println("Reset Clock"); resetClock(); break;
case 0x8309E8: Serial.println("Reserved"); break;
case 0x830AE8: Serial.println("Initialize player"); startGame();break;
case 0x830BE8: Serial.println("Explode player"); explodePlayer(); break;
case 0x830CE8: Serial.println("New game (ready)"); startGame(); break;
case 0x830DE8: Serial.println("Full health"); fullHealth(); break;
case 0x830EE8: Serial.println("Reserved"); break;
case 0x830FE8: Serial.println("Full armour"); armour = bodyArmourMax; break;
case 0x8310E8: Serial.println("Red Team = 0"); teamID = 0; break;
case 0x8311E8: Serial.println("Blue Team = 1"); teamID = 1; break;
case 0x8312E8: Serial.println("Yellow Team = 2"); teamID = 2; break;
case 0x8313E8: Serial.println("Green Team = 3"); teamID = 3; break;
case 0x8314E8: Serial.println("Clear scores"); break;
case 0x8315E8: Serial.println("Test sensors"); break;
case 0x8316E8: Serial.println("Stun player"); disarmPlayer(); break;
case 0x8317E8: Serial.println("Disarm player"); disarmPlayer(); break;
}
if (((results.value >> 16) & 0xFF) == 0x8A){ // clips pickup from 0-15
Serial.println("clips picked up");
mp3.playFileByIndexNumber(12); //add ammo
if((clips + results.value >> 8) > 0xFF){
clips = 0xFF;
} else{
clips += (results.value >> 8) & 0xFF;
}
Serial.print("Clips now at: ");
Serial.println(clips);
}
if (((results.value >> 16) & 0xFF) == 0x8B){ // health pickup mapped
Serial.println("health picked up");
mp3.playFileByIndexNumber(11); //medical
int addHealth = healthMapped(results.value >> 8);
if((health + addHealth) > respawnHealth){
health = respawnHealth;
} else{
clips += addHealth;
}
Serial.print("Health now at: ");
Serial.println(health);
}
if (((results.value >> 16) & 0xFF) == 0x8C){ // flags pickup from 0-15
mp3.playFileByIndexNumber(13); //blip
Serial.println("flag " + String((results.value >> 8) & 0xFF) + " picked up");
flagID[results.value >> 8] = true;
}
if (((results.value >> 16) & 0xFF) == 0xB4){ // team restore
Serial.println("Team " + String((results.value >> 8) & 0xFF) + " respawn detected");
if (((results.value >> 8) & 0xFF) == teamID){
respawn();
} else{
explodePlayer();
}
}
}
void adminKill (){
health = 0;
dead();
}
void fullAmmo(){
shotsLeft = magSize;
clips = magazines;
mp3.playFileByIndexNumber(12); //add ammo
}
void explodePlayer(){
mp3.playFileByIndexNumber(15); // Explode sound
health = 0;
dead();
}
void clearScores(){
memset(recPlayerHit, 0, maxHits);
memset(recTeamHit, 0, maxHits);
memset(recDamageHit, 0, maxHits);
memset(recZoneHit, 0, maxHits);
hitNo = 0;
mp3.playFileByIndexNumber(24); //blip
}
void fullHealth(){
mp3.playFileByIndexNumber(11); //medical
health = int(respawnHealth);
}
void disarmPlayer(){
shotsLeft = 0;
clips = 0;
mp3.playFileByIndexNumber(2); //disarm
}
Code Explanation:
The code in this section corresponds to the message table above.
if (((results.value >> 16) & 0xFF) == 0x8C) checks whether Byte 0 is equal to 0x8C, indicating that it is a flag.
flagID[results.value >> 8] = true; assigns the value of Byte 1 to the array flagID[].
Modify Code – IR tab

Code Explanation:
The Message package consists of 24 bits, which can be easily accessed using results.bits
through the IRremoteESP8266 library.
Christian Devotion
In laser tag, command messages serve as the invisible orchestrators of gameplay, transforming simple taggers into complex instruments of strategy. With a single digital signal, a tagger can suddenly gain health, receive additional ammunition, unlock a respawn capability, or become involved in a flag capture mission. The beauty of the laser tag command system lies in its ability to create diverse gameplay experiences. One moment, the game may feature a classic capture-the-flag scenario; the next, it could evolve into a multifaceted mission with numerous objectives and shifting rules.
The variety of power-ups in laser tag mirrors the range of spiritual gifts that God distributes among believers. In the game, some players might receive a shield upgrade, others may gain health, while some could enhance their weapons. Similarly, God bestows a diversity of gifts upon His people:
1 Corinthians 12:4–6 (NIV)
4 There are different kinds of gifts, but the same Spirit distributes them. 5 There are different kinds of service, but the same Lord. 6 There are different kinds of working, but in all of them and in everyone it is the same God at work.
When various game objects are used, players in laser tag must adapt their strategies rather than everyone performing the same role. They should capitalise on the potential power-up that a team member has received.
Consider how each power-up enhances a player’s effectiveness in the game. Similarly, spiritual gifts are not about comparison but about fulfilling one’s unique role in God’s grand strategy. God’s purpose in giving us spiritual gifts is to build up the church, so we should strategise on how to best utilise the gifts He has given us.
1 Corinthians 14:12 (NIV)
12 So it is with you. Since you are eager for gifts of the Spirit, try to excel in those that build up the church.
God has intentionally created us with diverse gifts so that Christians can work together to serve one another and the broader world. Problems may arise when we mistakenly believe we are gifted in a particular way, leading us to think we excel at something when we may not. It is always wise to approach gifts with humility, seeking input from others about where they believe you would best serve. Therefore, seek wisdom from God and others regarding where your strengths lie, so that as a church family, you can best capitalise on the gifts God has given you to serve the church and others.