Skip to main content

How to Create a Typewriter Effect in Batch Script

The "Typewriter Effect", where text appears on the screen character by character rather than all at once, is a classic way to add personality and dramatic flair to your Batch scripts. It is often used in game engines, intro splash screens, or scripts that aim to mimic an old-school mainframe terminal.

In this guide, we will demonstrate how to achieve this effect using a combination of string manipulation, loops, and short delays.

The Core Logic: Character Extraction

Because Batch does not have a built-in "typewriter" command, we have to:

  1. Store the message in a variable.
  2. Calculate the string length.
  3. Use a FOR /L loop to count through the indices of the string.
  4. Extract a single character at a time using substring syntax.
  5. Print that character without a newline using <nul set /p.
  6. Wait for a few milliseconds before printing the next character.

Method 1: The Standard Loop (Most Compatible)

This method works on any modern Windows system and uses the ping command to create short delays.

Implementation Script

@echo off
setlocal enabledelayedexpansion

set "msg=Initializing system protocols... Welcome, Administrator."

:loop
if "!msg!"=="" goto done

:: Extract first character
set "char=!msg:~0,1!"

:: Print it
<nul set /p "=!char!"

:: Remove first character
set "msg=!msg:~1!"

:: Delay (~50ms)
ping -n 1 -w 50 127.0.0.1 >nul

goto loop

:done
echo.
echo.

endlocal
pause

Explaining the code:

  • String length calculation: We calculate the length of the message dynamically using a binary search approach, so the loop iterates exactly the right number of times regardless of the message content. A sentinel character (x) is appended to avoid an off-by-one error in the length calculation.
  • !msg:~%%i,1!: This is string slicing. It takes the character at position %%i with a length of 1.
  • <nul set /p "=!char!": This is the key technique for typewriter effects. Normally, echo appends a carriage return and line feed. <nul set /p allows us to print text on the same line repeatedly without advancing to the next line.
  • ping -n 1 -w 50 127.0.0.1: Since Batch doesn't have a sleep command with millisecond precision, we ping the loopback address with a 50ms timeout to create a short delay. We use 127.0.0.1 instead of localhost to avoid DNS resolution overhead.

Method 2: The PowerShell-Timed Typewriter (Higher Precision)

If you need more precise timing control, you can call PowerShell's Start-Sleep -Milliseconds for each character. This is more accurate than the ping approach but slower to execute because each iteration spawns a PowerShell process.

@echo off
@echo off
setlocal enabledelayedexpansion

set "text=Establishing secure link... [DONE]"

:: Calculate string length with sentinel
set "s=!text!x"
set "len=0"
for %%n in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if not "!s:~%%n,1!"=="" (
set /a "len+=%%n"
set "s=!s:~%%n!"
)
)
set /a "lastIdx=len - 1"

:: Iterate through each character
for /L %%i in (0,1,!lastIdx!) do (
set "c=!text:~%%i,1!"
<nul set /p "=!c!"
powershell -nologo -noprofile -command "Start-Sleep -Milliseconds 40" >nul
)

echo.

endlocal
pause
info

Performance note: Each call to powershell in the loop spawns a new process, which adds significant overhead (typically 100–300ms per character on top of the requested delay). For short messages this is acceptable, but for long text the cumulative startup cost makes the effect feel sluggish. Method 1 using ping is generally faster in practice for typical typewriter speeds.

Adding a "Cursor Trail" Effect

To make it look even more authentic, you can display an underscore cursor that advances with each character, simulating a terminal cursor.

@echo off
setlocal enabledelayedexpansion

set "line=System Breach Detected..."

:: Compute string length
set "len=0"
set "s=!line!"
:len_loop
if defined s (
set "s=!s:~1!"
set /a len+=1
goto len_loop
)

:: Typewriter effect with blinking underscore
for /L %%i in (0,1,!len!-1) do (
set "char=!line:~%%i,1!"

:: Print character
<nul set /p "=!char!"

:: Print underscore
<nul set /p "=_"

:: Delay ~60ms
ping -n 1 -w 60 127.0.0.1 >nul

:: Move back to erase underscore
<nul set /p "="
)

:: Final newline
echo.

endlocal
pause

Practical Uses for the Typewriter Effect

  1. Storytelling: Adding narrative to text-based adventure games.
  2. User Onboarding: Explaining what a script is doing while simulating a conversational pace.
  3. Security Dashboards: Making log outputs look more "active" and monitored.

Summary Checklist

  1. Enable Delayed Expansion: You need setlocal enabledelayedexpansion to use !variable:~index,1! substring extraction inside the loop.
  2. Calculate String Length: Always calculate the message length dynamically rather than hardcoding the loop upper bound. This prevents the loop from running too few times (truncating the message) or too many times (printing nothing for extra iterations).
  3. Adjust the Speed: The higher the wait time in your ping or powershell call, the slower the "typing" will be. Values of 30–80ms typically look natural.
  4. Handle the End of Line: Always add a final echo. after your loop finishes so that the next command starts on a fresh line.

Conclusion

The typewriter effect is a simple but visually stunning addition to any Batch project. It turns a static message into a dynamic experience that engages the user. By mastering character extraction and the <nul set /p print trick, you can bring a touch of cinematic "terminal magic" to your everyday administrative scripts.