CS:GO stage lighting at home

About a year ago I went to a LAN-Party. For the first time in a long time I played Counter-Strike. also for the first time I had a really fun time playing because of the team spirit. After 10 minutes of playing we got into our first competition. Of course we failed miserably – but had a blast doing so.

The game really got to me in a good way. So the group that I went with started practicing. Of course just for he fun of it but it is really fun. Also I came across a few of the finals on youtube and that was when I saw it. The lighting on the stage.

If you don’t know what I’m talking about, have a look here:

The bomb goes off and they have flames and all sorts of cool things. Wouldn’t it be awesome if we could have that at home? (minus the flames)

Well, as it turns out – you can!

A friend of mine send me this link:
https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Game_State_Integration
That perfectly describes how to get game state information directly from the game client. Actually the site even have sample code available that works just like that!

So what do I need?

There are 3 parts in this setup.
1. the CS:GO Config file that tells the client what information to send.
2. the HTTP server that the client sends its data to.
3. the hardware that interface with the lighting or whatever you want it to.

Configuration file

following the site (see link above) I created a simple config for data retrieval:

I have deliberately removed everything that I didn’t need along with the authentication key. This is just for testing and I want to keep it simple.

One thing I did change after testing was the ‘heartbeat’ value. the standard was 60 seconds but the problem when debugging was that if I restarted the HTTP server it would take ages before I would another game state update. the heartbeat sets this interval so with a low value, even if I restart the server I get the game state pretty quickly.

HTTP Server

Again, the instruction page is really helpful. They provide a (simple) server written in Node.js. I have no experience with this, at all so how hard can it be?

I started with the provided file and then added a few things. I added a JSON deserializer so that I could do some logic on the game states. Then I installed ‘serialport’ so I could send a message to the hardware when I needed to.

The protocol is not pretty. really, it’s not. But it does the job. For each specific state I want to react on, I send a letter over the serial port. ‘b’ is for bomb (obviously). the rest is just the next letter in the alphabet. it’s simple and it works.

This is the complete code for the server:

At this time the serial port is hardcoded but it probably won’t matter much. maybe if I change to another USB port – uh-oh..

LED interface

Now for the fun part. the hardware.

again it’s really simple. just an Arduino with a strip of WS2812b LED’s on. Neopixels if you insist. Really, it’s nothing fancy. of course you can add whatever you want to on this platform so let’s look at the code instead.

The protocol just checks if a new char has arrived. if there is it sets the state accordingly

I have tried to condense the code and reuse the different blocks to save a bit of space.

Basically there are 4 ways of winning, 2 for each team

  1. Terrorists win by setting the bomb and making it explode
  2. Terrorists win by killing the other team
  3. Counter-terrorists win by defusing the bomb
  4. Counter terrorists win by killing the other team.

Each of these wins have a different light effect. The bomb, being the most visual, have a rainbow effect running across the LEDs. the other 3 are simply quick flashes of light either red, green or blue.

Lastly the controller can indicate the freezetime (a slow blue fade) and the ‘live’ time – the actual playing time (a slow yellow fade).

The really fun part was the bomb timing sequence.

Getting the timing right

So how do i synchronize the flashing to the beeps in-game? It turned out to be a bit harder than I thought.

The bomb beeps faster and faster. I started with just using 1 second between each beep and then making it 10ms faster for each beep. that worked but it was clear that the beeping was not linear. Sigh. but here is a challenge!

So to find out what was going on I recorded myself planting the bomb. Standing close to the bomb I could record the sound of the beeps.

This video I imported into Audacity for further analysis.

It’s pretty easy to see what’s going on. first, the ‘bomb has been planted’ voice-over. then a lot of beeps and then an explosion.

I was mostly interested in the beeping part so I removed the other stuff and normalized the beeps

The reason for normalizing the beeps was to utilize the ‘sound finder’ in audacity.

Setting the threshold really high I could make reasonably sure that I would only get the beeps and not any ambient sounds. There really are a lot of animal noises in the game! who whould have thought?

the Sound finder creates a ‘label’ track next to the sound.

The REALLY great thing is that the labels can be exported directly! pretty nifty!

I ended with a text file like this:

or rather – a list with the beginning and ending time of each beep. or at least a lot of them.

Next up was importing that list into libreOffice Calc (you can use Excel, that’s fine too!). First I found the time difference between each beep. Next, using the plotting tool I could find the polynomial expression for the time change.

Now, this is in seconds, so I wanted to convert to milliseconds. I multiply by 1000…

It turns out that it’s pretty close to:

0.1x^2-18x+1000

A quick plot on wolframAlpha reveals


Yeah, it’s pretty close. the reason it bottoms out is that I only did have the timing information from the first 65 or so beeps.

Using this formula I can calculate when the next beep should occur and thus when the next blink should be.

Now, action!

Let me just record a video of everything in action!

This was a really fun build. I was intrigued by the way the timer is made and it was great fun to find out the formula. I have only used free tools to solve this, OBS studio for recording, Audacity for audio analysis (FFMPEG plugin as well) and LibreOffice for plotting along with WolframAlpha.

Isn’t it great what can be achieved with free tools?

Leave a Reply