Library / SDK
huangkaoya/ts-redalert2 avatar
huangkaoya/ts-redalert2

RA2WEB React rebuilds a Red Alert 2 engine in TypeScript

红色警戒2源代码 Red Alert2 Source Code

1,018 stars262 forksTypeScriptNOASSERTION

At a glance

What is it?
ts-redalert2 is a browser based reimplementation of the Red Alert 2 engine, written in TypeScript with React, Three.js and Vite, and driven by a large set of Playwright regression scripts. It ships no art assets, its licence is GPL-3.0 with an added ban on commercial use, and the project states plainly that it is a study and research project.
Who is it for?
ts-redalert2 suits a developer who wants to study how a real time strategy engine is put together, or who wants to run the original game logic in a browser with their own legally obtained assets. It is the wrong project for commercial use, because the licence adds an explicit non-commercial restriction on top of GPL-3.0 and the upstream rights holder has not open sourced the client.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A whole RTS engine, rebuilt for the browser

The project is described as a complete TypeScript rewrite of Red Alert 2, a classic real time strategy game, built with React, TypeScript, Vite and Three.js. The English summary calls it RA2WEB React.

What makes it more than a demo is the scope of the directory layout. Under `src/` there is `data/` for the original asset formats, encoding, maps and the virtual file system, `engine/` for rendering, audio, asset loading and low level engine capabilities, `game/` for game logic, the object system, triggers, rules and superweapons, `gui/` for the main menu, HUD, options and in-game UI, `network/` for networking and multiplayer infrastructure, `tools/` for standalone tester pages, and `util/` for general utilities.

The game logic is the part that is genuinely difficult. `src/game/gameobject/` holds units, buildings, projectiles, traits and the locomotor, which is the movement model. `src/game/rules/` reads the original INI rule files and builds the object rules from them, so the game's behaviour comes from data rather than from hard coded logic. `src/game/trigger/` implements map triggers with conditions and executors, which is what makes maps work. `src/game/superweapon/` implements the nukes, the lightning storm and the superweapons.

On the rendering side, `src/engine/gfx/` is the Three.js layer with materials, batching, viewport handling and lighting, and `src/engine/renderable/` is the bridge that turns game objects into visible objects. `src/engine/sound/` does mixing, music and effects, and `src/engine/gameRes/` handles asset import, CDN loading, caching and directory handling.

The project states that it is developed from an analysis of the Chinese version of Chronodivide RA2WEB and is intended to be refactored onto current React and Three.js versions.

The licence and the ownership terms come before the code

This is the part of the project that a reader needs before a developer needs it, because the rights position is unusual and unusually emphatic.

The README states that the project is developed from the analysis of the Chinese version of Chronodivide RA2WEB, and that all rights to the project, including the profit rights, belong to the owner of Chronodivide. Without permission from that owner, any commercial use is strictly prohibited. It also records that the Chronodivide owner has never open sourced the game client code in any form, even though peripheral open source content such as a mod SDK exists.

The README goes further and lists what it considers infringement, including placing advertisements, developing a bullet screen Red Alert mode that profits from gifts, packaging and selling the project, and fraudulently obtaining sponsorship or donation revenue by claiming to be the author. It attributes the original author of Chronodivide as Alexandru Ciucă.

The licence section describes the project as open sourced under GNU General Public License v3.0, and then adds terms on top. You may use, modify and distribute freely, but commercial purposes are prohibited without permission from the RA2WEB lead. The copyright notice and licence text must be kept, any derivative work must use the same GPL-3.0 licence, source code must be provided including modified versions, and GPL code cannot be integrated into proprietary software. The repository's licence metadata is not classified as a standard licence by GitHub, so the LICENSE file is the text to read rather than the badge.

The asset question is separate and is stated clearly: the project ships no art, you import it locally from your own copy of the game, and the note tells you to make sure you own a legal copy. The asset formats are handled in `src/data/` and by the `@ra2web/pcxfile` and `@ra2web/wavefile` packages, and `7z-wasm` and `@ffmpeg/ffmpeg` are in the stack for archive and media handling.

Bun, Vite and a browser with three specific APIs

The toolchain is specified precisely, which is helpful because the runtime is not Node.

The package manager and local runtime is Bun 1.3.10, the development server is Vite 8.0.1, the UI is React 19.2.4 with react-dom 19.2.4, the type system is TypeScript 5.9.3, the renderer is three 0.183.2 and the automation is Playwright 1.58.2. The default development and preview address is `127.0.0.1:4000`, and the port is fixed at 4000 by convention, which is noted in the documentation alongside the other working agreements.

The browser requirements are listed as well. A modern browser is needed, with Chrome or Edge recommended, and the browser has to support WebGL, the Web Audio API and the File System Access API. The last one is the interesting constraint. The File System Access API is what lets a page read a local directory, which is how you point the engine at your own game assets without uploading them anywhere, and it is not available in every browser.

The install and start sequence is short.

bash
cd redalert2
bun install
bun run dev

and the production build and preview are two more commands.

bash
bun run build
bun run preview

The package manifest also carries a `test` script that runs `bun test`, so the unit test runner is Bun's own, and the `live:runtime` and `live:runtime:build` scripts point at a live interaction runtime, which is a separate harness from the Playwright flows.

The debug scripts are the real test suite

The project says it no longer relies only on manual clicking for verification, and that the `scripts/` directory maintains a set of directly executable regression scripts covering the lobby, entering a game, mechanics and the tester entry points.

The commands are named after the flow they exercise, and there are a lot of them.

bash
bun run debug:game-res-init
bun run debug:viewport
bun run debug:options
bun run debug:storage-explorer
bun run debug:skirmish
bun run debug:skirmish-lobby-data
bun run debug:victory-exit
bun run debug:superweapon
bun run debug:nuke
bun run debug:radiation
bun run debug:minimap-shroud
bun run debug:anti-air-hit
bun run debug:terror-drone
bun run debug:chrono-legionnaire
bun run debug:test-entries
bun run debug:tester-panels

The coverage tells you what the project considers risky. Asset initialisation, the viewport, the options screen, the storage explorer, the skirmish lobby, victory and exit, superweapons with a specific nuke and radiation test, minimap shroud, anti-air hit detection, the terror drone, the chrono legionnaire, and the tester pages themselves.

The artefacts from these runs are written to `.artifacts/` by default, which the documentation says makes it easy to review the screenshots and the JSON results afterwards. That is the design detail worth noticing. A screenshot and a JSON result per flow is a form of visual regression testing, and for a project whose output is a rendered 3D scene, that is close to the only way to assert on behaviour automatically.

The contribution guidance is explicit about which scripts to run. Before submitting changes it suggests at least `bun run typecheck:entry` and `bun run build`, and if the change touches the lobby, asset loading, entering a game, the HUD, the mechanics or the tester, the corresponding `debug:*` scripts should be run as well.

The testers are debugging surfaces, not showcase demos

The main menu has test entries, and the project is careful about what they are.

There are three groups. The asset tests are `VXL测试`, `SHP测试` and `音频测试`, covering the three original asset formats the engine has to read: voxel graphics, sprite format and audio. The mechanic tests are `建筑测试`, `载具测试`, `步兵测试` and `飞行器测试`, for buildings, vehicles, infantry and aircraft. The scene tests are `大厅测试`, `世界测试` and `移动测试`, covering the lobby, the world and movement.

The documentation is explicit that these tester pages are not isolated demos, and that they are an important debugging and regression entry point in the repository. The state of the panel on the left side of the page is synchronised to a debug state object, and the automation scripts use these entries directly to verify rendering and interaction results.

That is a stronger claim than it sounds. A tester page that only displays a model is a demo. A tester page that the automated scripts drive, whose panel state is published into a state object the scripts read, is a test fixture. The project is using the same surface for a human debugging session and for a Playwright assertion, which means the fixtures cannot quietly drift away from what a developer actually uses.

The `src/tools/` directory holds these pages as standalone tester pages, and the description of that directory says they are currently an important entry point for visualising debugging results and for automation assertions.

The source tree mirrors the game's own subsystems

The directory layout is the clearest description of the architecture, and it is organised by concern in a way that a reader of the original engine would recognise.

`src/engine/gfx/` holds the Three.js render layer with its materials, batching, viewport and lighting, and `src/engine/renderable/` is described as the bridging layer between game objects and visual objects. That separation is the one that matters in a game engine, because the simulation must be able to run faster or slower than the frame rate, and the renderer must not be allowed to know how the simulation works.

`src/engine/sound/` covers mixing, music and effects playback, and `src/engine/gameRes/` covers asset import, CDN loading, caching and directory handling. The CDN loading is worth noting, since it implies the engine can fetch assets over the network as well as from the local file system, and the File System Access API requirement in the browser is the local half of that.

`src/gui/` is split into `screen/mainMenu/`, which holds the main menu, map selection, the lobby and the options, `screen/game/` for the in-game HUD, world interaction and menus, `component/` for React components, and `jsx/` for a custom UI rendering bridge. That last directory is a hint that the original game's UI, which was drawn with its own immediate mode renderer, is being reproduced through a bridge rather than by rewriting every screen as React components.

The documentation also records the working agreements. The development port is fixed at 4000, the main technical alignment records are kept in `docs/build-alignment-log.md`, and automation artefacts go to `.artifacts/`. The alignment log matters, because the project warns that a passing build does not mean all behaviour is fully aligned and that functional questions should be settled with the dedicated scripts and real flows.

Where a browser engine is the wrong answer

The limitations are not technical ones so much as legal and practical ones, and they should be read before any code is written.

The first is the licence and the ownership position. The project carries GPL-3.0 and then adds a prohibition on commercial use without permission from the RA2WEB lead, which is a restriction on top of the GPL rather than the plain GPL. It also states that the upstream owner has never open sourced the client code. For a project, a company or a product, that combination is a blocker, and the disclaimer names the commercial patterns it considers infringement, which is a fairly clear statement that the author expects misuse attempts and has thought about them.

The second is the asset dependency. The engine reads the original formats, VXL for voxel graphics, SHP for sprites, PCX and WAV for media, and the INI rules, and it does not ship any of it. The user supplies the files from a copy of the game they own, which is the second half of the legal position and the part a reader has to take responsibility for.

The third is the browser platform itself. The File System Access API requirement narrows the audience, WebGL rules out a low end machine as a realistic target for a large battle, and the whole design puts a browser between the game and the hardware. A team that needs the original game running at high fidelity on a real machine, or that needs a commercially licensed engine, is in a different category.

There is also a project-management limit worth naming. The documentation says the project is intended to be refactored onto the latest React and Three.js versions, which describes a codebase in motion rather than a settled one, and the alignment log exists precisely because behaviour parity is tracked item by item rather than assumed. Anyone planning to base work on this should expect to read the alignment log first, because that is where the honest list of what matches and what does not lives.

Editorial conclusion

ts-redalert2 suits a developer who wants to study how a real time strategy engine is put together, or who wants to run the original game logic in a browser with their own legally obtained assets. It is the wrong project for commercial use, because the licence adds an explicit non-commercial restriction on top of GPL-3.0 and the upstream rights holder has not open sourced the client. Check first the licence file and the ownership disclaimers before you contribute anything, and read `docs/build-alignment-log.md`, because the project is explicit that a passing build does not mean the behaviour matches the original.

Frequently asked questions

What is RA2WEB React?

It is a complete TypeScript rewrite of the Red Alert 2 game engine that runs in a browser, built with React, TypeScript, Vite and Three.js. The game logic, rules, triggers, superweapons, rendering, audio and asset handling are reimplemented rather than wrapped.

How do I build and run the project?

You need Bun 1.3 or newer and a modern browser with WebGL, the Web Audio API and the File System Access API. Run `bun install` and `bun run dev` in the `redalert2` directory, then open `http://127.0.0.1:4000`. For a production build use `bun run build` and `bun run preview`.

Can I use this project commercially?

No, not without permission from the RA2WEB lead. The project is released under GPL-3.0 and the README adds that commercial use is strictly prohibited without that permission, that derivatives must keep the same licence and provide source, and that GPL code cannot be integrated into proprietary software. It is stated to be for learning and research only.

Where do the game assets come from?

The repository ships no art. You import the Red Alert 2 assets locally from your own copy of the game, and the documentation notes that you should make sure you own a legal copy. The engine reads the original formats directly, including VXL, SHP, PCX and WAV, and the INI rule files.

Official sources

  1. huangkaoya/ts-redalert2 on GitHub
  2. Issues
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/huangkaoya-ts-redalert2.svg)](https://hysenlabs.com/projects/huangkaoya-ts-redalert2)

Was this useful?