├── LICENSE ├── README.md ├── game-integrations ├── CSGO │ ├── CSGO.csp │ └── payload │ │ ├── capsule.jpg │ │ ├── config │ │ └── csgo │ │ │ └── cfg │ │ │ └── gamestate_integration_chromasync.cfg │ │ ├── details.json │ │ └── scripts │ │ └── csgo_integration.lua └── ChromaCraft │ ├── ChromaCraft.1.3.csp │ └── payload │ ├── capsule.jpg │ ├── details.json │ ├── mod │ └── chromacraft-1.3.jar │ └── scripts │ └── chromacraft.lua └── sample-lua-scripts ├── CSGO_main.lua ├── README.md ├── random_flash_main.lua └── sweep.lua /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChromaSync SDK 2 | 3 | Chroma Sync is the easiest way to sync games and apps, and create beautiful and reactive lighting effects. 4 | 5 | The SDK provides a means of interacting with Chroma Sync in a relatively simple manner either via the simple API or via Lua scripts. 6 | 7 | ##Main Features 8 | 9 | ###The Chroma Sync API 10 | Developers can provide built-in support for Chroma Sync thanks to it's simple to use API. Community developers can even create mods/plugins for their favourite apps/games to provide support via the API. Anyone can then customise their own effects via Lua scripts. 11 | 12 | ###Built-in Lua support 13 | Anyone can customise in-game effects supported by Chroma Sync or even script beautiful lighting effects that would be impossible with Razer's Chroma Configurator. 14 | 15 | ## So, API or Lua? 16 | 17 | In simple terms, the API handles the **input** from other apps/games, whereas Lua consumes it and provides the logic for the lighting effects - or **output**. 18 | 19 | It works like so: 20 | 21 | 1. A Game/Application can send data to Chroma Sync via an API 22 | 2. In order for the data to be consumed, a Lua script must register to receive the data 23 | 3. Lua script consumes the data and is responsible for the lighting effects 24 | 25 | Note that Lua scripts can also work independently, and is perfect for those who want to create totally custom lighting effects/animations. 26 | -------------------------------------------------------------------------------- /game-integrations/CSGO/CSGO.csp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njbmartin/chromasync-sdk/20c481102106381e31fb2bd9e641d20c6243a046/game-integrations/CSGO/CSGO.csp -------------------------------------------------------------------------------- /game-integrations/CSGO/payload/capsule.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njbmartin/chromasync-sdk/20c481102106381e31fb2bd9e641d20c6243a046/game-integrations/CSGO/payload/capsule.jpg -------------------------------------------------------------------------------- /game-integrations/CSGO/payload/config/csgo/cfg/gamestate_integration_chromasync.cfg: -------------------------------------------------------------------------------- 1 | "Razer Chroma" 2 | { 3 | "uri" "http://localhost:13000" 4 | "timeout" "5.0" 5 | "buffer" "0.1" 6 | "throttle" "0.5" 7 | "heartbeat" "10.0" 8 | "auth" 9 | { 10 | "razer" "chroma" 11 | } 12 | "data" 13 | { 14 | "provider" "1" 15 | "map" "1" 16 | "round" "1" 17 | "player_id" "1" 18 | "player_state" "1" 19 | "player_weapons" "1" 20 | "player_match_stats" "1" 21 | } 22 | } -------------------------------------------------------------------------------- /game-integrations/CSGO/payload/details.json: -------------------------------------------------------------------------------- 1 | { 2 | "product":{ 3 | "name":"CS:GO Chromatic", 4 | "author":"Razer Official", 5 | "description":"Provides awesome effects for CSGO", 6 | "version":"1.1", 7 | "type":"Game" 8 | }, 9 | "installation":[ 10 | { 11 | "action":"extract", 12 | "folder":"config", 13 | "destination":{ 14 | "type":"steamapp", 15 | "folder":"Counter-Strike Global Offensive" 16 | } 17 | }, 18 | { 19 | "action":"extract", 20 | "folder": "scripts", 21 | "destination": { 22 | "type": "folder", 23 | "folder": "%appdata%\\ChromaSync\\scripts" 24 | } 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /game-integrations/CSGO/payload/scripts/csgo_integration.lua: -------------------------------------------------------------------------------- 1 | -- All functions must sit within a unique class 2 | -- This prevents any conflicts with other lua scripts 3 | CSGO_Example = {} 4 | 5 | local Colore = clr.Corale.Colore 6 | local Razer = Colore.Razer 7 | local Thread = clr.System.Threading.Thread 8 | 9 | 10 | -- Theme Options 11 | 12 | local Theme = { 13 | Colors = { 14 | None = Colore.Core.Color(20, 20, 20), 15 | Dead = Colore.Core.Color(255, 0, 0), 16 | Freeze = Colore.Core.Color(255, 255, 255), 17 | Lite = Colore.Core.Color(50, 50, 50), 18 | Menu = Colore.Core.Color(255, 255, 255), 19 | Counter = Colore.Core.Color(0, 0, 255), 20 | Terrorists = Colore.Core.Color(255, 69, 0), 21 | Health = { 22 | Low = Colore.Core.Color(60, 0, 0), 23 | Full = Colore.Core.Color(255, 0, 0) 24 | }, 25 | Weapon = { 26 | Inactive = Colore.Core.Color(60, 0, 0), 27 | Active = Colore.Core.Color(0, 255, 0) 28 | }, 29 | Armor = { 30 | Low = Colore.Core.Color(60, 0, 0), 31 | Full = Colore.Core.Color(255, 255, 255) 32 | }, 33 | 34 | Ammo = { 35 | Low = Colore.Core.Color(60, 0, 0), 36 | Full = Colore.Core.Color(255, 255, 0) 37 | } 38 | } 39 | } 40 | 41 | local Colors = { 42 | Background = Colore.Core.Color(255, 69, 0), 43 | One = Colore.Core.Color.Red, 44 | Two = Colore.Core.Color.Red, 45 | Three = Colore.Core.Color(255,140,0), 46 | } 47 | 48 | -- CS:GO Specific fields 49 | 50 | local _team = "NA" 51 | local _isAnimating = false 52 | local _phase = "NA" 53 | local _activity = "NA" 54 | local _helmet = false 55 | local _planted = false 56 | local _flashed = false 57 | local _burning = false 58 | 59 | 60 | 61 | function CSGO_Example.SetAll(color) 62 | Colore.Core.Chroma.Instance.SetAll(color) 63 | end 64 | 65 | 66 | function CSGO_Example.SetNumpad(color) 67 | 68 | for x=0,5 do 69 | for y=15,21 do 70 | Keyboard[x,y] = color 71 | end 72 | end 73 | 74 | end 75 | 76 | -- FreezeTime Animation 77 | CSGO_Example.FreezeTime = coroutine.create(function () 78 | local mousepadNumber = 0 79 | while true do 80 | _isAnimating = true 81 | if _phase ~= "freezetime" then 82 | CSGO_Example.SetTeam(_team) 83 | _isAnimating = false 84 | coroutine.yield() 85 | end 86 | --Keyboard.SetAll(Colore.Core.Color.Pink) 87 | if mousepadNumber > 7 then 88 | Keyboard.SetKey(Razer.Keyboard.Key.Escape, Theme.Colors.Freeze) 89 | CSGO_Example.SetNumpad(Theme.Colors.Freeze) 90 | else 91 | Keyboard.SetKey(Razer.Keyboard.Key.Escape, Colore.Core.Color.Black) 92 | CSGO_Example.SetNumpad(Theme.Colors.None) 93 | end 94 | Mousepad.SetAll(Theme.Colors.None) 95 | Mousepad[mousepadNumber] = Theme.Colors.Freeze 96 | Thread.Sleep(50) 97 | 98 | mousepadNumber = mousepadNumber + 1 99 | if mousepadNumber >= 15 then 100 | mousepadNumber = 0 101 | end 102 | end 103 | end) 104 | 105 | -- Flashed Animation 106 | CSGO_Example.Flashed = coroutine.create(function () 107 | local mousepadNumber = 0 108 | while true do 109 | 110 | _isAnimating = true 111 | if _flashed == false then 112 | CSGO_Example.SetTeam(_team) 113 | _isAnimating = false 114 | coroutine.yield() 115 | end 116 | 117 | if _helmet == false then 118 | _flashed = false 119 | CSGO_Example.SetTeam(_team) 120 | _isAnimating = false 121 | coroutine.yield() 122 | end 123 | 124 | --Keyboard.SetAll(Colore.Core.Color.Pink) 125 | 126 | CSGO_Example.SetAll(Theme.Colors.Freeze) 127 | Thread.Sleep(100) 128 | end 129 | end) 130 | 131 | CSGO_Example.Burning = coroutine.create(function () 132 | while true do 133 | _isAnimating = true 134 | if _burning ~= true then 135 | CSGO_Example.SetTeam(_team) 136 | _isAnimating = false 137 | coroutine.yield() 138 | end 139 | 140 | if _helmet == false then 141 | CSGO_Example.SetTeam(_team) 142 | _isAnimating = false 143 | coroutine.yield() 144 | end 145 | 146 | -- set keyboard colour 147 | 148 | CSGO_Example.SetAll(Theme.Colors.Terrorists) 149 | 150 | for x=0,5 do 151 | Keyboard[math.random(0,6), math.random(0,22)] = Colors.One 152 | end 153 | 154 | -- set mousepad colour 155 | Mousepad[math.random(0,15)] = Colors.One 156 | 157 | 158 | -- set mouse colour 159 | Mouse[math.random(0,9), math.random(0,7)] = Colors.One 160 | 161 | 162 | -- set keypad colour 163 | 164 | Keypad[math.random(0,4),math.random(0,5)] = Colors.One 165 | 166 | -- We don't want to spam the SDK, so throttle to 50ms 167 | Thread.Sleep(60) 168 | end 169 | end) 170 | 171 | CSGO_Example.Planted = coroutine.create(function () 172 | while true do 173 | _isAnimating = true 174 | if _planted ~= "planted" then 175 | CSGO_Example.SetTeam(_team) 176 | _isAnimating = false 177 | coroutine.yield() 178 | end 179 | 180 | if _helmet == false then 181 | CSGO_Example.SetTeam(_team) 182 | _isAnimating = false 183 | coroutine.yield() 184 | end 185 | 186 | --Keyboard.SetAll(Colore.Core.Color.Pink) 187 | Keyboard.SetKey(Razer.Keyboard.Key.D5, Theme.Colors.Dead) 188 | CSGO_Example.SetNumpad(Theme.Colors.Dead) 189 | 190 | Mousepad.SetAll(Theme.Colors.Dead) 191 | 192 | 193 | Thread.Sleep(500) 194 | --Keyboard.SetAll(Colore.Core.Color.Blue) 195 | Keyboard.SetKey(Razer.Keyboard.Key.D5, Theme.Colors.None) 196 | Mousepad.SetAll(Theme.Colors.None) 197 | CSGO_Example.SetNumpad(Theme.Colors.None) 198 | Thread.Sleep(500) 199 | end 200 | end) 201 | 202 | function CSGO_Example.RoundHandler(round) 203 | if _activity == "playing" then 204 | if round["phase"] ~= _phase then 205 | --DebugLua("phase changed: " .. round["phase"]) 206 | _phase = round["phase"] 207 | end 208 | 209 | if round["bomb"] ~= _planted then 210 | --DebugLua("phase changed: " .. round["phase"]) 211 | _planted = round["bomb"] 212 | end 213 | 214 | 215 | if _planted == "planted" then -- Check if Phase is FreezeTime 216 | --DebugLua("phase is now freezetime") 217 | 218 | coroutine.resume(CSGO_Example.Planted) 219 | end 220 | 221 | if _phase == "freezetime" then -- Check if Phase is FreezeTime 222 | --DebugLua("phase is now freezetime") 223 | coroutine.resume(CSGO_Example.FreezeTime) 224 | end 225 | end 226 | 227 | end 228 | function CSGO_Example.PlayerHandler(player) 229 | 230 | if player["activity"] ~= _activity then 231 | _activity = player["activity"] 232 | 233 | if _activity == "menu" then 234 | _team = "NA" 235 | _burning = false 236 | _flashed = false 237 | _planted = false 238 | _phase = "NA" 239 | CSGO_Example.SetAll(Theme.Colors.Terrorists) 240 | Keyboard.SetKey(Razer.Keyboard.Key.C, Theme.Colors.Menu) 241 | Keyboard.SetKey(Razer.Keyboard.Key.S, Theme.Colors.Menu) 242 | Keyboard.SetKey(Razer.Keyboard.Key.G, Theme.Colors.Menu) 243 | Keyboard.SetKey(Razer.Keyboard.Key.O, Theme.Colors.Menu) 244 | do return end 245 | 246 | end 247 | 248 | end 249 | 250 | if _activity == "menu" then 251 | _team = "NA" 252 | _burning = false 253 | _flashed = false 254 | _planted = false 255 | _phase = "NA" 256 | do return end 257 | end 258 | 259 | if player["state"]["flashed"] > 0 then 260 | _flashed = true 261 | --DebugLua(player["state"]["flashed"]) 262 | coroutine.resume(CSGO_Example.Flashed) 263 | do return end 264 | else 265 | _flashed = false 266 | end 267 | 268 | if player["state"]["burning"] > 0 then 269 | _burning = true 270 | --DebugLua(player["state"]["burning"]) 271 | coroutine.resume(CSGO_Example.Burning) 272 | do return end 273 | else 274 | _burning = false 275 | end 276 | 277 | if player["state"] ~= nil then 278 | if player["state"]["helmet"] ~= _helmet then 279 | _helmet = player["state"]["helmet"] 280 | if _helmet == false then 281 | CSGO_Example.SetAll(Colore.Core.Color.Red) 282 | _team = "NA" 283 | do return end 284 | end 285 | end 286 | 287 | if _team ~= player["team"] then 288 | _team = player["team"] 289 | CSGO_Example.SetTeam(_team) 290 | end 291 | 292 | if (_activity ~="menu" and _helmet) then 293 | local health = math.ceil((4 / 100) * ConvertInt(player["state"]["health"])) 294 | for i=1, 4 do 295 | if health >= i then 296 | Keyboard[0,6+i]= Theme.Colors.Health.Full 297 | else 298 | Keyboard[0,6+i]= Theme.Colors.None 299 | end 300 | end 301 | 302 | local armor = math.ceil((4 / 100) * ConvertInt(player["state"]["armor"])) 303 | for i=1, 4 do 304 | if armor >= i then 305 | Keyboard[0,10+i]= Theme.Colors.Armor.Full 306 | else 307 | Keyboard[0,10+i]= Theme.Colors.None 308 | end 309 | end 310 | 311 | -- WEAPONS 312 | 313 | local Set = { 314 | One = Theme.Colors.None, 315 | Two = Theme.Colors.None, 316 | Three = Theme.Colors.None, 317 | Four = Theme.Colors.None, 318 | Five = Theme.Colors.None 319 | } 320 | 321 | for i=0,10 do --pseudocode 322 | local color = Theme.Colors.None 323 | --Keyboard[1,1+i]= Theme.Colors.None 324 | local weapon = player["weapons"]["weapon_" .. i] 325 | if weapon ~= nil then 326 | local type= weapon["type"] 327 | 328 | if type == "Pistol" then 329 | color = Theme.Colors.Weapon.Inactive 330 | if weapon["state"]== "active" then 331 | color = Theme.Colors.Weapon.Active 332 | end 333 | Set.Two = color 334 | elseif type == "Knife" then 335 | color = Theme.Colors.Weapon.Inactive 336 | if weapon["state"] == "active" then 337 | color = Theme.Colors.Weapon.Active 338 | end 339 | Set.Three = color 340 | 341 | elseif type == "Grenade" then 342 | color = Theme.Colors.Weapon.Inactive 343 | if weapon["state"] == "active" then 344 | color = Theme.Colors.Weapon.Active 345 | end 346 | Set.Four = color 347 | elseif type == "C4" then 348 | color = Theme.Colors.Weapon.Inactive 349 | if weapon["state"] == "active" then 350 | color = Theme.Colors.Weapon.Active 351 | end 352 | Set.Five = color 353 | else 354 | color = Theme.Colors.Weapon.Inactive 355 | if weapon["state"] == "active" then 356 | color = Theme.Colors.Weapon.Active 357 | end 358 | Set.One = color 359 | end 360 | 361 | 362 | -- Current Ammo 363 | local ammo = weapon["ammo_clip"] 364 | if (weapon["state"] == "active" and ammo ~= nil) then 365 | local keyboardTotal = math.ceil((4 / ConvertInt(weapon["ammo_clip_max"])) * ConvertInt(ammo)) 366 | local mouseTotal = math.ceil((7 / ConvertInt(weapon["ammo_clip_max"])) * ConvertInt(ammo)) 367 | local mouseCustom = NewCustom("mouse") 368 | c = Theme.Colors.Ammo.Full 369 | 370 | if (mouseTotal < 3) then 371 | c = Theme.Colors.Ammo.Low 372 | 373 | end 374 | 375 | for i=1, 7 do 376 | 377 | if(i >= mouseTotal) then 378 | c = Theme.Colors.None 379 | end 380 | 381 | Mouse[i,0] = c 382 | Mouse[i,6] = c 383 | 384 | end 385 | 386 | c = Theme.Colors.Ammo.Full 387 | 388 | if (keyboardTotal < 2) then 389 | c = Theme.Colors.Ammo.Low 390 | Keyboard.SetKey(Razer.Keyboard.Key.R, Theme.Colors.Menu) 391 | else 392 | c = Theme.Colors.Ammo.Full 393 | Keyboard.SetKey(Razer.Keyboard.Key.R, Theme.Colors.None) 394 | end 395 | 396 | for i=0, 3 do 397 | 398 | if(i >= keyboardTotal) then 399 | c = Theme.Colors.None 400 | end 401 | Keyboard[0, 3 + i] = c 402 | end 403 | 404 | 405 | end 406 | end 407 | end 408 | Keyboard.SetKey(Razer.Keyboard.Key.D1, Set.One) 409 | Keyboard.SetKey(Razer.Keyboard.Key.D2, Set.Two) 410 | Keyboard.SetKey(Razer.Keyboard.Key.D3, Set.Three) 411 | Keyboard.SetKey(Razer.Keyboard.Key.D4, Set.Four) 412 | Keyboard.SetKey(Razer.Keyboard.Key.D5, Set.Five) 413 | end 414 | end 415 | end 416 | 417 | function CSGO_Example.SetTeam(team) 418 | --DebugLua("team: " .. _team) 419 | 420 | if _activity ~= "menu" then 421 | if team == "CT" then 422 | CSGO_Example.SetAll(Theme.Colors.Counter) 423 | else 424 | CSGO_Example.SetAll(Theme.Colors.Terrorists) 425 | end 426 | -- WASD 427 | Keyboard.SetKey(Razer.Keyboard.Key.W, Theme.Colors.Menu) 428 | Keyboard.SetKey(Razer.Keyboard.Key.A, Theme.Colors.Menu) 429 | Keyboard.SetKey(Razer.Keyboard.Key.S, Theme.Colors.Menu) 430 | Keyboard.SetKey(Razer.Keyboard.Key.D, Theme.Colors.Menu) 431 | 432 | else 433 | _team = "NA" 434 | end 435 | end 436 | 437 | -- our main function to handle the data 438 | function CSGO_Example.handleData(json) 439 | -- Get the current phase (if any) 440 | player = json["player"] 441 | CSGO_Example.PlayerHandler(player) 442 | round = json["round"] 443 | if round ~= nil then 444 | CSGO_Example.RoundHandler(round) 445 | end 446 | --phase = json["round"]["phase"] 447 | --CSGO_Example.PhaseHandler(phase) 448 | 449 | end 450 | 451 | -- Finally, we must register this script in order to receive data 452 | RegisterForEvents("Counter-Strike: Global Offensive", CSGO_Example.handleData) -------------------------------------------------------------------------------- /game-integrations/ChromaCraft/ChromaCraft.1.3.csp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njbmartin/chromasync-sdk/20c481102106381e31fb2bd9e641d20c6243a046/game-integrations/ChromaCraft/ChromaCraft.1.3.csp -------------------------------------------------------------------------------- /game-integrations/ChromaCraft/payload/capsule.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njbmartin/chromasync-sdk/20c481102106381e31fb2bd9e641d20c6243a046/game-integrations/ChromaCraft/payload/capsule.jpg -------------------------------------------------------------------------------- /game-integrations/ChromaCraft/payload/details.json: -------------------------------------------------------------------------------- 1 | { 2 | "product":{ 3 | "name":"ChromaCraft", 4 | "author":"KeithM", 5 | "description":"Provides visual feedback for in-game Minecraft events", 6 | "version":"1.3.0", 7 | "type":"Game" 8 | }, 9 | "installation":[ 10 | { 11 | "action":"extract", 12 | "folder": "mod", 13 | "destination": { 14 | "type": "folder", 15 | "folder": "%appdata%\\.minecraft\\mods" 16 | } 17 | }, 18 | { 19 | "action":"extract", 20 | "folder": "scripts", 21 | "destination": { 22 | "type": "folder", 23 | "folder": "%appdata%\\ChromaSync\\scripts" 24 | } 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /game-integrations/ChromaCraft/payload/mod/chromacraft-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njbmartin/chromasync-sdk/20c481102106381e31fb2bd9e641d20c6243a046/game-integrations/ChromaCraft/payload/mod/chromacraft-1.3.jar -------------------------------------------------------------------------------- /game-integrations/ChromaCraft/payload/scripts/chromacraft.lua: -------------------------------------------------------------------------------- 1 | Minecraft_Example = {} 2 | 3 | local colore = clr.Corale.Colore.Core 4 | -- local keyboard = colore.Keyboard.Instance 5 | local thread = clr.System.Threading.Thread 6 | 7 | local background_color = colore.Color.Black 8 | local isRaining = false 9 | local time = 12000 10 | 11 | local showingBackground = false 12 | local showingDeathBackground = false 13 | local showingFireBackground = false 14 | 15 | local fireColors = {colore.Color.Orange, colore.Color.Yellow, colore.Color(255, 55, 0), colore.Color(255, 136, 0), colore.Color(255, 196, 0)} 16 | 17 | Minecraft_Example.GenerateBackground = coroutine.create(function () 18 | while true do 19 | if showingBackground == false then 20 | Keyboard.SetAll(background_color) 21 | Mouse.SetAll(background_color) 22 | Mousepad.SetAll(background_color) 23 | coroutine.yield() 24 | end 25 | local timeconvert = math.ceil((254 / 23999) * ConvertInt(time)) 26 | c = colore.Color(timeconvert, 0, 255-timeconvert); 27 | for x = 0, 17 do 28 | Keyboard[5, x] = c 29 | Keyboard[4, x] = c 30 | end 31 | 32 | thread.Sleep(25) 33 | end 34 | end) 35 | 36 | Minecraft_Example.HandleDeath = coroutine.create(function () 37 | while true do 38 | local time = 0 39 | while time < 255 do 40 | if showingDeathBackground == false then 41 | Keyboard.SetAll(background_color) 42 | Mouse.SetAll(background_color) 43 | Mousepad.SetAll(background_color) 44 | coroutine.yield() 45 | end 46 | c = colore.Color((254 - time),0,0) 47 | Keyboard.SetAll(c) 48 | Mouse.SetAll(c) 49 | Mousepad.SetAll(c) 50 | 51 | time = time + 1 52 | thread.Sleep(2) 53 | end 54 | end 55 | end) 56 | 57 | Minecraft_Example.HandleFire = coroutine.create(function () 58 | while true do 59 | if showingFireBackground == false then 60 | Keyboard.SetAll(background_color) 61 | Mouse.SetAll(background_color) 62 | Mousepad.SetAll(background_color) 63 | coroutine.yield() 64 | end 65 | 66 | -- local randomInt = math.random(4) 67 | 68 | Keyboard.SetAll(colore.Color.Red) 69 | for x=0, 21 do 70 | local height = math.random(5) 71 | for y=0, height do 72 | randomInt = math.random(4) 73 | c = fireColors[randomInt] 74 | Keyboard[5-y,x] = c 75 | end 76 | end 77 | Mouse.SetAll(colore.Color.Red) 78 | for i=0, 6 do 79 | local height = math.random(4, 5) 80 | 81 | if(i < height) then 82 | randomInt2 = math.random(4) 83 | c = fireColors[randomInt2] 84 | Mouse[17 - i] = c 85 | Mouse[10 - i] = c 86 | end 87 | end 88 | Mousepad.SetAll(colore.Color.Red) 89 | for i=0, 13 do 90 | randomInt2 = math.random(4) 91 | c = fireColors[randomInt2] 92 | Mousepad[i] = c 93 | end 94 | thread.Sleep(100) 95 | end 96 | end) 97 | 98 | function Minecraft_Example.SetAll(color) 99 | for x=0,5 do 100 | for y=0,21 do 101 | Keyboard[x,y] = color 102 | end 103 | end 104 | end 105 | 106 | function Minecraft_Example.HandleHealth(json) 107 | --keyboard.SetAll(colore.Color(255,0,0)) 108 | local healthTotal = math.ceil((12 / ConvertInt(json["player"]["maxhealth"])) * ConvertInt(json["player"]["health"])) 109 | for i=1, 12 do 110 | c = colore.Color.Red 111 | if (i >= 5) then 112 | c = colore.Color.Orange 113 | end 114 | if (i >= 9) then 115 | c = colore.Color.Green 116 | end 117 | if i > healthTotal then 118 | c = background_color 119 | end 120 | Keyboard[0,i + 2] = c 121 | 122 | end 123 | 124 | local healthTotal2 = math.ceil((6 / ConvertInt(json["player"]["maxhealth"])) * ConvertInt(json["player"]["health"])) 125 | for i=0, 6 do 126 | c = colore.Color.Red 127 | 128 | if(i < 2) then 129 | if(i < healthTotal2) then 130 | Mouse[2] = colore.Color.Red 131 | end 132 | end 133 | if (i > 2) then 134 | c = colore.Color.Orange 135 | end 136 | if (i > 4) then 137 | if (i <= healthTotal2+1) then 138 | Mouse[1] = colore.Color.Green 139 | else 140 | Mouse[1] = colore.Color.Black 141 | end 142 | c = colore.Color.Green 143 | end 144 | 145 | if(i > healthTotal2) then 146 | c = colore.Color.Black 147 | end 148 | 149 | Mouse[17 - i] = c 150 | Mouse[10 - i] = c 151 | end 152 | 153 | local healthTotal3 = math.ceil((8 / ConvertInt(json["player"]["maxhealth"])) * ConvertInt(json["player"]["health"])) 154 | for i=0, 7 do 155 | c = colore.Color.Red 156 | if (i > 2) then 157 | c = colore.Color(255, 140, 0) 158 | end 159 | if (i > 5) then 160 | c = colore.Color.Green 161 | end 162 | if i >= healthTotal3 then 163 | c = colore.Color.Black 164 | end 165 | Mousepad[7+i] = c 166 | Mousepad[7-i] = c 167 | end 168 | end 169 | function Minecraft_Example.HandleHotbar(json) 170 | for i=1, 9 do 171 | c = colore.Color.Blue 172 | if (i-1 == ConvertInt(json["player"]["hotbar"]["selected"])) then 173 | c = colore.Color.White 174 | end 175 | Keyboard[1,i + 1] = c 176 | end 177 | end 178 | function Minecraft_Example.HandlePotions(json) 179 | for i=0, 8 do 180 | c = background_color 181 | if #json["player"]["potioneffects"] > 0 then 182 | if i < #json["player"]["potioneffects"] then 183 | local effect = json["player"]["potioneffects"][i] 184 | local colors = effect["color"] 185 | 186 | local red = ConvertInt(colors["r"]) 187 | local green = ConvertInt(colors["g"]) 188 | local blue = ConvertInt(colors["b"]) 189 | 190 | -- DebugLua(i .. ": " .. effect["name"] .. " R: " .. red .. " G: " .. green .. " B: " .. blue) 191 | 192 | c = colore.Color (red,green,blue) 193 | 194 | end 195 | end 196 | 197 | local x = 0; 198 | local y = 0; 199 | 200 | if i == 0 then 201 | x = 0; 202 | y = 0; 203 | end 204 | if i == 1 then 205 | x = 1; 206 | y = 0; 207 | end 208 | if i == 2 then 209 | x = 2; 210 | y = 0; 211 | end 212 | if i == 3 then 213 | x = 0; 214 | y = 1; 215 | end 216 | if i == 4 then 217 | x = 1; 218 | y = 1; 219 | end 220 | if i == 5 then 221 | x = 2; 222 | y = 1; 223 | end 224 | if i == 6 then 225 | x = 0; 226 | y = 2; 227 | end 228 | if i == 7 then 229 | x = 1; 230 | y = 2; 231 | end 232 | if i == 8 then 233 | x = 2; 234 | y = 2; 235 | end 236 | Keyboard[2+y,18+x] = c 237 | end 238 | end 239 | function Minecraft_Example.HandleKeys(json) 240 | c = colore.Color.Green 241 | Keyboard[2,3] = c 242 | Keyboard[3,3] = c 243 | Keyboard[3,2] = c 244 | Keyboard[3,4] = c 245 | Keyboard[2,6] = c 246 | end 247 | 248 | -- our main function to handle the data 249 | -- JSON Container format: https://gist.github.com/MusicalCreeper01/12c340c532501cd67e1e 250 | function Minecraft_Example.handleData(json) 251 | time = json["player"]["time"] 252 | isRaining = json["player"]["raining"] 253 | if json["player"]["isDead"] == true then 254 | showingDeathBackground = true 255 | showingFireBackground = false 256 | showingBackground = false 257 | if coroutine.status(Minecraft_Example.HandleDeath) ~= "running" then 258 | coroutine.resume(Minecraft_Example.HandleDeath) 259 | end 260 | elseif json["player"]["inFire"] == true then 261 | showingFireBackground = true 262 | showingBackground = false 263 | if coroutine.status(Minecraft_Example.HandleFire) ~= "running" then 264 | coroutine.resume(Minecraft_Example.HandleFire) 265 | end 266 | else 267 | showingDeathBackground = false 268 | showingFireBackground = false 269 | showingBackground = true 270 | --if coroutine.status(Minecraft_Example.GenerateBackground) ~= "running" then 271 | --coroutine.resume(Minecraft_Example.GenerateBackground) 272 | --end 273 | Minecraft_Example.HandleHealth(json) 274 | Minecraft_Example.HandleHotbar(json) 275 | Minecraft_Example.HandlePotions(json) 276 | Minecraft_Example.HandleKeys(json) 277 | end 278 | end 279 | 280 | -- Finally, we must register this script in order to receive data 281 | RegisterForEvents("Minecraft", Minecraft_Example.handleData) -------------------------------------------------------------------------------- /sample-lua-scripts/CSGO_main.lua: -------------------------------------------------------------------------------- 1 | -- All functions must sit within a unique class 2 | -- This prevents any conflicts with other lua scripts 3 | CSGO_Example = {} 4 | 5 | local Colore = clr.Corale.Colore 6 | local Razer = Colore.Razer 7 | local Thread = clr.System.Threading.Thread 8 | 9 | -- CS:GO Specific fields 10 | 11 | local team = "NA" 12 | local _isAnimating = false 13 | local _phase = "NA" 14 | local _activity = "NA" 15 | local _helmet = false 16 | 17 | -- FreezeTime Animation 18 | CSGO_Example.FreezeTime = coroutine.create(function () 19 | Keyboard.SetAll(Colore.Core.Color.Pink) 20 | while true do 21 | _isAnimating = true 22 | if _phase == "live" then 23 | 24 | CSGO_Example.SetTeam(_team) 25 | _isAnimating = false 26 | coroutine.yield() 27 | end 28 | --Keyboard.SetAll(Colore.Core.Color.Pink) 29 | Keyboard.SetKey(Razer.Keyboard.Key.Escape, Colore.Core.Color.White) 30 | Thread.Sleep(200) 31 | --Keyboard.SetAll(Colore.Core.Color.Blue) 32 | Keyboard.SetKey(Razer.Keyboard.Key.Escape, Colore.Core.Color.Black) 33 | Thread.Sleep(200) 34 | end 35 | end) 36 | 37 | 38 | function CSGO_Example.RoundHandler(round) 39 | if round["phase"] ~= _phase then 40 | --DebugLua("phase changed: " .. round["phase"]) 41 | _phase = round["phase"] 42 | end 43 | 44 | if _phase == "freezetime" then -- Check if Phase is FreezeTime 45 | --DebugLua("phase is now freezetime") 46 | coroutine.resume(CSGO_Example.FreezeTime) 47 | end 48 | end 49 | 50 | 51 | function CSGO_Example.PlayerHandler(player) 52 | if player["activity"] ~= _activity then 53 | _activity = player["activity"] 54 | 55 | if _activity == "menu" then 56 | Keyboard.SetAll(Colore.Core.Color.White) 57 | else 58 | CSGO_Example.SetTeam(player["team"]) 59 | end 60 | end 61 | DebugLua("helmet: " .. player["state"]["helmet"]) 62 | if player["state"]["helmet"] ~= _helmet then 63 | _helmet = player["state"]["helmet"] 64 | if _helmet then 65 | CSGO_Example.SetTeam(_team) 66 | else 67 | Keyboard.SetAll(Colore.Core.Color.Red) 68 | end 69 | end 70 | 71 | end 72 | 73 | 74 | function CSGO_Example.SetTeam(team) 75 | _team = team 76 | if _team == "CT" then 77 | Keyboard.SetAll(Colore.Core.Color.Blue) 78 | else 79 | Keyboard.SetAll(Colore.Core.Color(255,255,255)) 80 | end 81 | end 82 | 83 | -- our main function to handle the data 84 | function CSGO_Example.handleData(json) 85 | -- Get the current phase (if any) 86 | 87 | player = json["player"] 88 | DebugLua("Got player data") 89 | CSGO_Example.PlayerHandler(player) 90 | 91 | round = json["round"] 92 | CSGO_Example.RoundHandler(round) 93 | 94 | 95 | --phase = json["round"]["phase"] 96 | --CSGO_Example.PhaseHandler(phase) 97 | 98 | end 99 | 100 | -- Finally, we must register this script in order to receive data 101 | RegisterForEvents("Counter-Strike: Global Offensive", CSGO_Example.handleData) 102 | -------------------------------------------------------------------------------- /sample-lua-scripts/README.md: -------------------------------------------------------------------------------- 1 | # Sample Lua Scripts 2 | 3 | Chroma Sync allows you to create beautiful and reactive standalone lighting effects. 4 | 5 | Provided are a number of samples to get you going and to help you understand how to interact with Chroma Devices. 6 | 7 | ## Installation 8 | 9 | Chroma Sync will soon have the ability to easily create, share and install user-made scripts (similar to game integrations). Until then, it's still possible to do all this manually. 10 | 11 | Lua scripts live within the `%appdata%\ChromaSync\scripts` folder. Chroma Sync will detect when a `.lua` file has been created or modified, and will restart all scripts. 12 | 13 | ## Issues 14 | 15 | If Chroma Sync runs into any problems - including lua scripts - all errors are logged to `%appdata%\ChromaSync\logs`. Please note that it may not be able to provide the specific issue, but most errors tend to be simple spelling or syntax mistakes. 16 | -------------------------------------------------------------------------------- /sample-lua-scripts/random_flash_main.lua: -------------------------------------------------------------------------------- 1 | local Colore = clr.Corale.Colore.Core 2 | local Thread = clr.System.Threading.Thread 3 | 4 | function play_anim() 5 | while true do 6 | -- Everthing should be white (strobe effect!!!!) 7 | c = Colore.Color.White 8 | background = Colore.Color.Black 9 | -- set keyboard colour 10 | Keyboard.SetPosition(math.random(0,5), math.random(1,18), c, true) 11 | -- set mousepad colour 12 | Mousepad.SetAll(background) 13 | Mousepad[math.random(0,15)] = c 14 | Mousepad[math.random(0,15)] = c 15 | Mousepad[math.random(0,15)] = c 16 | -- set mouse colour 17 | Mouse.SetAll(background) 18 | Mouse[math.random(0,9), math.random(0,7)] = c 19 | Mouse[math.random(0,9), math.random(0,7)] = c 20 | Mouse[math.random(0,9), math.random(0,7)] = c 21 | 22 | -- set keypad colour 23 | Keypad.SetAll(background) 24 | Keypad[math.random(0,4),math.random(0,5)] = c 25 | Keypad[math.random(0,4),math.random(0,5)] = c 26 | Keypad[math.random(0,4),math.random(0,5)] = c 27 | 28 | -- We don't want to spam the SDK, so throttle to 50ms 29 | Thread.Sleep(50) 30 | end 31 | end 32 | 33 | play_anim() 34 | -------------------------------------------------------------------------------- /sample-lua-scripts/sweep.lua: -------------------------------------------------------------------------------- 1 | local Colore = clr.Corale.Colore 2 | local rgb = Colore.Core.Color 3 | local Razer = Colore.Razer 4 | local Thread = clr.System.Threading.Thread 5 | 6 | local Memory = { 7 | Keyboard = { 8 | X = 0, 9 | Y = 0, 10 | }, 11 | Color = 0.00, 12 | } 13 | 14 | util = { 15 | maxcolumns = Razer.Keyboard.Constants.MaxColumns, -- The maximum amount of columns we can use, without crashing. 16 | maxrows = Razer.Keyboard.Constants.MaxRows, -- The maximum amount of rows we can use, without crashing. 17 | } 18 | 19 | function randomColor() 20 | r,g,b = hsvToRgb(math.random(),1,math.random()) 21 | return rgb(r,g,b) 22 | end 23 | 24 | function hsvToRgb(h, s, v, a) 25 | local r, g, b 26 | local i = math.floor(h * 6); 27 | local f = h * 6 - i; 28 | local p = v * (1 - s); 29 | local q = v * (1 - f * s); 30 | local t = v * (1 - (1 - f) * s); 31 | i = i % 6 32 | if i == 0 then r, g, b = v, t, p 33 | elseif i == 1 then r, g, b = q, v, p 34 | elseif i == 2 then r, g, b = p, v, t 35 | elseif i == 3 then r, g, b = p, q, v 36 | elseif i == 4 then r, g, b = t, p, v 37 | elseif i == 5 then r, g, b = v, p, q 38 | end 39 | return r * 255, g * 255, b * 255 40 | end 41 | 42 | function row(n, colour) 43 | n = n <= util.maxrows-1 and n >= 0 and n or 0 44 | for i=0,21 do 45 | Keyboard[n,i] = colour 46 | end 47 | end 48 | 49 | function column(n, colour) 50 | n = n <= util.maxcolumns-1 and n >= 0 and n or 0 51 | for i=0,5 do 52 | Keyboard[i,n] = colour 53 | end 54 | end 55 | 56 | function fill(colour, fancy) 57 | if fancy then 58 | local c = true; 59 | for i=0,(util.maxcolumns+util.maxrows) do 60 | for x=0,30 do 61 | Keyboard[math.random(0,util.maxrows),math.random(0,util.maxcolumns)] = colour 62 | end 63 | Thread.Sleep(60) 64 | end 65 | end 66 | Keyboard.SetAll(colour) 67 | end 68 | 69 | function play_anim() 70 | c = rgb; 71 | -- set the background. 72 | Keyboard.SetAll(c.Purple) -- Makes the whole keyboard purple. 73 | Keyboard.SetKey(Razer.Keyboard.Key.Escape, c(255,0,0)) -- Makes the Escape key red. 74 | -- For other keys see https://coralestudios.github.io/Colore/docs/_key_8cs.html 75 | Thread.Sleep(1000) -- This is about a 1 second delay. 76 | 77 | while true do 78 | local cols = {randomColor(), randomColor(), randomColor(), randomColor()} 79 | -- set keyboard colour 80 | for i=0,5 do 81 | row(i, cols[1]) 82 | Thread.Sleep(60) 83 | end 84 | 85 | for i=5,0,-1 do 86 | row(i, cols[2]) 87 | Thread.Sleep(60) 88 | end 89 | 90 | for i=0,21 do 91 | column(i, cols[3]) 92 | Thread.Sleep(60) 93 | end 94 | 95 | for i=21,0,-1 do 96 | column(i, cols[4]) 97 | Thread.Sleep(60) 98 | end 99 | 100 | fill(randomColor(), true) 101 | 102 | -- We don't want to spam the SDK, so throttle to 50ms 103 | Thread.Sleep(50) 104 | end 105 | end 106 | 107 | play_anim() 108 | --------------------------------------------------------------------------------