Actualizado:

1. Preparación (una vez)

/scoreboard objectives add wave dummy "Oleada"
/scoreboard objectives add left dummy
/scoreboard objectives setdisplay sidebar wave
/scoreboard players set #game wave 0

wave guarda la oleada actual y left cuántos enemigos quedan.

2. Generar enemigos en los marcadores

/execute at @e[type=marker,tag=spawn] run summon zombie ~ ~ ~ {Tags:["enemy"],PersistenceRequired:1b}

Aparece un zombi en cada marcador de aparición. La etiqueta enemy permite contar solo las criaturas de esta partida. Coloca marcadores alrededor de la arena con /summon marker ~ ~ ~ {Tags:["spawn"]}.

3. Contar enemigos (Iterativo)

/execute store result score #game left if entity @e[tag=enemy]

Usa un bloque Iterativo en Siempre activo; el número de enemigos etiquetados va a left (consulta execute store).

4. Siguiente oleada cuando mueren todos

/execute if score #game left matches 0 run scoreboard players add #game wave 1
/execute if score #game left matches 0 run title @a title {"text":"¡Siguiente oleada!","color":"red"}
/execute if score #game left matches 0 at @e[type=marker,tag=spawn] run summon zombie ~ ~ ~ {Tags:["enemy"],PersistenceRequired:1b}

Encadénalos después del paso 3. Añade líneas con if score #game wave matches 5.. para criaturas más duras; consulta los comandos de zombis.

5. Fin de la partida

/execute unless entity @a[gamemode=adventure] run tellraw @a [{"text":"¡Fin de la partida! Oleada alcanzada: ","color":"red"},{"score":{"name":"#game","objective":"wave"}}]

Pasa a espectador a los jugadores caídos para que la comprobación funcione, y luego elimina a los enemigos con /kill @e[tag=enemy].

6. Enemigos más duros en oleadas posteriores

# añadir después de la cadena del paso 4
execute if score #game left matches 0 if score #game wave matches 5.. at @e[type=marker,tag=spawn] run summon skeleton ~ ~ ~ {Tags:["enemy"],PersistenceRequired:1b}

Desde la oleada 5, los esqueletos se unen a los zombis. El paso 4 sube primero el número de oleada, así que esta línea ve la oleada nueva. Añade una línea con 10.. para oleadas aún más avanzadas.

7. Un jefe en la oleada 10 (Java 1.21.5+)

execute if score #game left matches 0 if score #game wave matches 10 at @e[type=marker,tag=spawn,limit=1] run summon zombie ~ ~ ~ {Tags:["enemy"],PersistenceRequired:1b,CustomName:"Jefe",CustomNameVisible:1b,attributes:[{id:"minecraft:max_health",base:100}],Health:100f}

Solo la oleada 10 trae un zombi con nombre y 100 de salud; limit=1 hace que haya un solo jefe. En la 1.21.4 y anteriores escribe CustomName:'"Jefe"'. Consulta el comando de jefes.

Solución de problemas

Comprueba tu comando

El Command Error Doctor (en inglés) revisa en tu navegador los errores de sintaxis más comunes.