Package RustRaptor and refine controls, menus, saves, sound and mod selection
This commit is contained in:
1 parent
0844f6dffa
commit
e17bc1003e
649 files changed
+8637
-2662
No files matched your search
+5
-1
@@ -1,5 +1,6 @@
|
||||
# Derived game data — extracted from the copyrighted originals, never commit
|
||||
data/
|
||||
RustRaptor/data/
|
||||
|
||||
# Vendored raptor build output
|
||||
raptor/build/
|
||||
@@ -13,9 +14,12 @@ __pycache__/
|
||||
|
||||
# Rust builds and locally derived reference/preview data
|
||||
target/
|
||||
RustRaptor/target/
|
||||
RustRaptor/dist/
|
||||
RustRaptor/.reference/
|
||||
.reference/
|
||||
derived/
|
||||
|
||||
# Decoded original style references are not shipped mod artwork.
|
||||
examples/mods/*/art/source/
|
||||
RustRaptor/mods/*/art/source/
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# Rust rewrite milestones
|
||||
|
||||
The C++ engine remains playable and retained as a reference. The Rust engine runs independently alongside it on branch `codex/rust-rewrite`. Both are selectable through `play.sh`. Original catalog/reference assets remain ignored; authored mod images and sounds are tracked in Git.
|
||||
|
||||
The registered game has three sectors with nine waves each. Archive slots are asset containers, not five independent campaigns.
|
||||
|
||||
## Implemented
|
||||
|
||||
- Checked asset decoders, typed namespaced registries and original content registration.
|
||||
- Independent integer simulation at 70/3 Hz; deterministic RNG and SDL2 input/interpolated indexed rendering.
|
||||
- Original / Scale2x / Scale3x / Scale4x modes, joined terrain filtering, sharp bitmap text and separate derived cache.
|
||||
- Rust MUS, GENMIDI FM synthesis and digital DSP mixing, with native PCM comparisons.
|
||||
- Menus, shop, equipment, mission selection, pilot slots, atomic saves, read-only legacy import and original AGX cinematics.
|
||||
- Local mods, dependencies/conflicts, explicit overrides/priority/hashes, bounded deterministic Rhai hooks and transactional commands.
|
||||
- In-game enable/disable and pending changes, save diagnostics, schemas, validation CLI and scripted Aurora example.
|
||||
- Optional source-hashed HD loader/setting; one accepted player-frame proof with original fallback.
|
||||
- C++/Rust replay recording and comparison tools, synthetic tests and local-original-data checks.
|
||||
|
||||
## Acceptance gates
|
||||
|
||||
1. **Foundation and complete playable first mission:** verify the entire mission through its boss, damage, rewards, collision/order and RNG against the rebuilt reference. Short replay equality is evidence, not completion of this gate.
|
||||
2. **Complete game:** verify all 27 waves and four difficulties, equipment, training/campaign progression, cinematics, demos, menus and legacy imports.
|
||||
3. **Modding release:** finish lifecycle/error/save acceptance and stabilize API version 1.
|
||||
4. **Visual completion and cutover:** approve complete sprite sequences, check palette/layer/clipping/seam fidelity at 1080p and measure display performance. Make Rust the default only after preceding gates pass.
|
||||
|
||||
Not all gates have passed. See [validation instructions](docs/rust-rewrite.md) and [HD coverage](docs/hd-art.md). Online mod distribution, an editor, total conversions, external MIDI/SoundFonts and additional desktop targets remain outside scope.
|
||||
|
||||
## New content
|
||||
|
||||
Separate agents are building Iron Coast mission 1, three individual weapon mods and three individual enemy mods using the public API. Each package will ship local SD/HD artwork and procedurally generated sound effects, with definitions, scripts, images and sounds tracked together in Git. These packages remain in development until validation and play tests pass.
|
||||
@@ -1,21 +1,19 @@
|
||||
# RaptorReplica
|
||||
|
||||
A Linux replica of Raptor: Call of the Shadows, with the retained C++ engine and an independent Rust engine under development.
|
||||
[RustRaptor](RustRaptor/README.md) contains the independent Rust game, bundled mods,
|
||||
SD/HD artwork, sound effects, schemas, tests and build tools. Rust is the default:
|
||||
|
||||
```sh
|
||||
./play.sh --engine rust
|
||||
./play.sh --engine legacy
|
||||
./play.sh
|
||||
```
|
||||
|
||||
The C++ engine remains the launcher default while Rust gameplay parity and full-game acceptance are verified. Rust includes SDL2 input, interpolated indexed rendering, audio, all 27 original mission definitions, deterministic simulation, pilot slots, separate saves, cinematics, an in-game mod manager, bounded Rhai scripting, crisp sprite filters and an optional HD artwork setting.
|
||||
You can also run `./RustRaptor/run.sh`. The game loads your existing `data/`
|
||||
catalog; choose bundled mods from its **Mods** menu. Mod images and sounds are
|
||||
tracked in Git alongside their definitions and scripts.
|
||||
|
||||
The local HD proof replaces one player frame; other frames use original artwork. It is not a complete remaster. Longer reference replays, full campaign playthroughs and presentation fidelity remain in validation.
|
||||
The retained source under `raptor/` is an optional reference. It is not required
|
||||
to build or play RustRaptor. `./play.sh --engine legacy` runs that reference.
|
||||
|
||||
- [Building and running](docs/building.md)
|
||||
- [Rust implementation and validation](docs/rust-rewrite.md)
|
||||
- [Mod API and schemas](docs/modding-api.md)
|
||||
- [Optional HD artwork](docs/hd-art.md)
|
||||
- [Asset extraction](docs/asset-pipeline.md)
|
||||
- [Milestones](PLAN.md)
|
||||
|
||||
Code is GPL-2.0-or-later; the vendored Rust FM emulator is LGPL-2.1-or-later. Original game catalog assets, local HD remaster proofs, builds, caches and recordings stay outside Git. Authored mod SD/HD images and sounds are included in Git. Supply your own licensed data in `data/`.
|
||||
See [Rust build and validation](RustRaptor/docs/rust-rewrite.md),
|
||||
[modding API](RustRaptor/docs/modding-api.md), and
|
||||
[Iron Coast packages](RustRaptor/docs/iron-coast.md).
|
||||
Generated
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Rust rewrite milestones
|
||||
|
||||
The independent Rust engine is the default launcher on branch `codex/rust-rewrite`. Its source, mods, schemas, tests and documentation live in `RustRaptor/`. The retained C++ checkout is optional reference material. Original catalog/reference assets remain ignored; authored mod images and sounds are tracked in Git.
|
||||
|
||||
The registered game has three sectors with nine waves each. Archive slots are asset containers, not five independent campaigns.
|
||||
|
||||
## Implemented
|
||||
|
||||
- Checked asset decoders, typed namespaced registries and original content registration.
|
||||
- Independent integer simulation at 70/3 Hz; deterministic RNG and SDL2 input/interpolated indexed rendering.
|
||||
- Original / Scale2x / Scale3x / Scale4x modes, joined terrain filtering, sharp bitmap text and separate derived cache.
|
||||
- Rust MUS, GENMIDI FM synthesis and digital DSP mixing, with native PCM comparisons.
|
||||
- Menus, shop, equipment, mission selection, pilot slots, atomic saves, read-only legacy import and original AGX cinematics.
|
||||
- Local mods, dependencies/conflicts, explicit overrides/priority/hashes, bounded deterministic Rhai hooks and transactional commands.
|
||||
- In-game enable/disable and pending changes, save diagnostics, schemas, validation CLI and scripted Aurora example.
|
||||
- Optional source-hashed HD loader/setting; one accepted player-frame proof with original fallback.
|
||||
- C++/Rust replay recording and comparison tools, synthetic tests and local-original-data checks.
|
||||
|
||||
## Validation and remaining work
|
||||
|
||||
1. **Playable first mission:** fresh pilots win through the boss at difficulties 1 and 2 using deterministic input and predictive steering. The complete 1,889-step original demo matches all captured native gameplay fields. Wider ordinary playtesting remains useful.
|
||||
2. **Complete game coverage:** all 27 waves complete at each of four difficulties under an assisted fixture; all original weapons, training/campaign progression, legacy import and cinematics have checks. These fixtures do not establish exhaustive native parity or every menu/save route.
|
||||
3. **Mod API version 1:** dependencies, overrides, script limits/errors, atomic enable/disable and incompatible saves have regressions. The bundled mission, weapons and enemies validate and have controlled playthroughs.
|
||||
4. **Visual treatment:** complete sampled sprite sequences, palette shadows and joined terrain pass local checks; the desktop renderer has SD/HD 1080p measurements. The base-game HD remaster is partial. Rust is the default at the user's request; finishing every reference comparison is not a prerequisite to playing it.
|
||||
|
||||
See [validation instructions](docs/rust-rewrite.md) and [HD coverage](docs/hd-art.md) for the evidence and its limits. Online mod distribution, an editor, total conversions, external MIDI/SoundFonts and additional desktop targets remain outside scope.
|
||||
|
||||
## New content
|
||||
|
||||
Separate agents built Iron Coast mission 1, three individual weapon mods and three individual enemy mods using the public API. Each package ships local SD/HD artwork and procedurally generated sound effects, with definitions, scripts, images and sounds tracked together in Git. The mission dependencies and two controlled victories are documented in [Iron Coast](docs/iron-coast.md).
|
||||
@@ -0,0 +1,77 @@
|
||||
# RustRaptor
|
||||
|
||||
The independent Linux Rust game and its complete local mod packages live here.
|
||||
SDL2 handles platform services; gameplay, asset decoding, rendering, audio,
|
||||
saving and mod scripting run in Rust.
|
||||
|
||||
From the repository root:
|
||||
|
||||
```sh
|
||||
./play.sh
|
||||
```
|
||||
|
||||
Or from this folder:
|
||||
|
||||
```sh
|
||||
./run.sh
|
||||
cargo test --locked
|
||||
```
|
||||
|
||||
Supply the original game catalog in `../data/` or `RustRaptor/data/`. You can
|
||||
select another catalog with `--data DIR`. No C++ checkout or build is needed to
|
||||
build or play the Rust game. Some optional comparison tests use retained source.
|
||||
|
||||
The **Mods** screen discovers the bundled `mods/` packages when no user mods
|
||||
folder exists. Enable the Iron Coast mission package to select its six
|
||||
dependencies automatically, then apply at the main menu. The three weapons can also be enabled individually.
|
||||
For a user mods folder, pass `--mods DIR` or create
|
||||
`$XDG_DATA_HOME/RaptorReplica/mods/`. Saves and configuration use separate XDG
|
||||
`RaptorReplica` directories, with read-only legacy import.
|
||||
|
||||
Enter the **Hangar** to fly, choose missions, visit the supply room, manage
|
||||
equipment or **Save pilot**. New pilots have editable names, callsigns and ID
|
||||
pictures and difficulty; existing pilots can edit their ID from the hangar.
|
||||
Registration starts with 10,000 credits and 75 energy, as in the original.
|
||||
The supply room
|
||||
shows an equipment image, description, price, resale value, quantity and
|
||||
whether it fires automatically, is selectable, is consumed or works passively.
|
||||
|
||||
Default keyboard controls are arrow keys to move, **Ctrl** to fire,
|
||||
**Space** to drop a bomb, **Alt or Shift** to cycle equipment, and **Z** to
|
||||
use a selected consumable. Custom bindings remain configurable in Options.
|
||||
Existing untouched Rust default bindings migrate to these controls.
|
||||
|
||||
| Folder | Contents |
|
||||
| --- | --- |
|
||||
| `src/` | Engine, SDL host and validation CLI |
|
||||
| `mods/` | Aurora example, Iron Coast mission, three weapons and three enemies |
|
||||
| `schemas/` | Version 1 mod API schemas |
|
||||
| `tests/` | Portable fixtures and opt-in original-data checks |
|
||||
| `tools/` | Replay comparator, content-table generator and asset reference tools |
|
||||
| `docs/` | API, artwork, build and validation documentation |
|
||||
| `target/` | Local Cargo builds, excluded from Git |
|
||||
|
||||
All bundled mod definitions, scripts, SD/HD PNGs, WAVs, generation prompts and
|
||||
recipes are tracked in Git. Original data and local reference pixels are excluded.
|
||||
The engine supports original and 2×/3×/4× crisp scaling, plus an optional HD
|
||||
artwork setting. Bundled mods have SD/HD artwork; the base-game HD proof covers
|
||||
one player frame, with crisp originals supplying the other frames.
|
||||
|
||||
First-mission wins at difficulties 1 and 2, a complete 1,889-step native demo
|
||||
comparison, assisted coverage of all 27 missions at four difficulties, and
|
||||
sample-exact audio comparisons have passed. These checks cover their documented
|
||||
cases; wider playtesting and complete base-game HD coverage remain work in progress.
|
||||
|
||||
- [Build and validation](docs/rust-rewrite.md)
|
||||
- [Mod API](docs/modding-api.md)
|
||||
- [Iron Coast packages](docs/iron-coast.md)
|
||||
- [Weapon prices and balance](docs/weapon-balance.md)
|
||||
- [Sprite and shadow validation](docs/visual-validation.md)
|
||||
- [Sound playback validation](docs/sound-validation.md)
|
||||
- [Display measurements](docs/performance.md)
|
||||
- [First mission](docs/first-mission-validation.md)
|
||||
- [Campaign coverage](docs/campaign-validation.md)
|
||||
- [Optional HD artwork](docs/hd-art.md)
|
||||
- [Milestones](PLAN.md)
|
||||
|
||||
Code is GPL-2.0-or-later; the vendored Rust FM emulator is LGPL-2.1-or-later.
|
||||
File renamed without changes.
@@ -26,17 +26,17 @@ reported outcome or its 12,000-step inspection limit.
|
||||
|
||||
The final run visited every spawn record, observed every expected boss instance
|
||||
and finished with no remaining enemies. Its local CSV is
|
||||
`.reference/campaign-validation.csv` (SHA-256
|
||||
`8702d190a039239de154e09ebbb5972f6d7ffe07475d7d47b199b53efb3a811a`).
|
||||
`../.reference/campaign-validation-final.csv` (SHA-256
|
||||
`c4e1fc0ca1199efd2a9e72ceb7ebbe3d71325b517cb9829995138ead99486901`).
|
||||
|
||||
| Difficulty | Completed waves | Steps per wave | Enabled spawns | Boss instances seen | Nonpositive last health | Positive last health |
|
||||
| --- | ---: | --- | ---: | ---: | ---: | ---: |
|
||||
| 0 | 27 | 4,601–4,873 | 3,751 | 88 | 53 | 35 |
|
||||
| 1 | 27 | 4,607–4,873 | 3,751 | 88 | 53 | 35 |
|
||||
| 2 | 27 | 4,651–5,079 | 6,259 | 88 | 36 | 52 |
|
||||
| 3 | 27 | 4,650–5,082 | 8,668 | 88 | 37 | 51 |
|
||||
| 2 | 27 | 4,651–5,079 | 6,259 | 88 | 37 | 51 |
|
||||
| 3 | 27 | 4,650–5,082 | 8,668 | 88 | 36 | 52 |
|
||||
|
||||
The 108 runs cover 513,002 simulation steps, 22,429 enabled spawns and 352 boss
|
||||
The 108 runs cover 513,003 simulation steps, 22,429 enabled spawns and 352 boss
|
||||
appearances. Boss retirement counts classify the health observed immediately
|
||||
before removal: 179 nonpositive and 173 positive. Positive health commonly
|
||||
indicates a boss leaving the screen; damage and removal within the same step
|
||||
@@ -52,10 +52,10 @@ training's four-wave route, each normal 27-wave route, difficulty promotion,
|
||||
campaign resets and the training reward. They call the progression API directly
|
||||
and bypass combat; end cinematics and menu transitions need separate checks.
|
||||
|
||||
Run the four original-data integration tests from the project directory:
|
||||
Run the four original-data integration tests from the `RustRaptor/` directory:
|
||||
|
||||
```sh
|
||||
RAPTOR_CAMPAIGN_REPORT=.reference/campaign-validation.csv \
|
||||
RAPTOR_CAMPAIGN_REPORT=../.reference/campaign-validation-final.csv \
|
||||
cargo test --release --no-default-features --test campaigns -- --ignored --nocapture
|
||||
```
|
||||
|
||||
@@ -72,26 +72,26 @@ cargo build --release --no-default-features --lib
|
||||
rustc --edition=2024 tools/campaign_check.rs \
|
||||
--extern raptor_replica=target/release/deps/libraptor_replica-HASH.rlib \
|
||||
--extern anyhow=target/release/deps/libanyhow-HASH.rlib \
|
||||
-L dependency=target/release/deps -o .reference/campaign-check
|
||||
.reference/campaign-check data
|
||||
-L dependency=target/release/deps -o ../.reference/campaign-check
|
||||
../.reference/campaign-check ../data
|
||||
```
|
||||
|
||||
Its optional second argument selects one difficulty, for example
|
||||
`.reference/campaign-check data 3`.
|
||||
`../.reference/campaign-check ../data 3`.
|
||||
|
||||
## Reproduce the complete demo comparison
|
||||
|
||||
Rebuild the retained C++ source before capturing a reference. The local debug
|
||||
build used `.reference/cpp-rng-build`; use the available CMake executable if it
|
||||
build used `../.reference/cpp-rng-build`; use the available CMake executable if it
|
||||
is outside `PATH`. Prepare an isolated legacy profile with `raptorsetup`, or
|
||||
copy an existing `SETUP.INI` into `.reference/full-demo-profile/Raptor/` before
|
||||
copy an existing `SETUP.INI` into `../.reference/full-demo-profile/Raptor/` before
|
||||
running the following commands. The original executable requires `data/` as its
|
||||
working directory. A complete reference takes about 81 seconds at 70/3 Hz.
|
||||
|
||||
```sh
|
||||
cmake --build .reference/cpp-rng-build --parallel 4
|
||||
cmake --build ../.reference/cpp-rng-build --parallel 4
|
||||
(
|
||||
cd data
|
||||
cd ../data
|
||||
XDG_DATA_HOME="$PWD/../.reference/full-demo-profile" \
|
||||
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
||||
RAPTOR_REFERENCE_TRACE="$PWD/../.reference/cpp-demo1-full.jsonl" \
|
||||
@@ -99,9 +99,9 @@ cmake --build .reference/cpp-rng-build --parallel 4
|
||||
../.reference/cpp-rng-build/bin/raptor PLAY demos/DEMO1G1_REC
|
||||
)
|
||||
cargo run --no-default-features -- \
|
||||
--replay DEMO1G1_REC --ticks 1889 --trace .reference/rust-demo1-full.jsonl
|
||||
--replay DEMO1G1_REC --ticks 1889 --trace ../.reference/rust-demo1-full.jsonl
|
||||
python3 tools/compare_replays.py \
|
||||
.reference/cpp-demo1-full.jsonl .reference/rust-demo1-full.jsonl
|
||||
../.reference/cpp-demo1-full.jsonl ../.reference/rust-demo1-full.jsonl
|
||||
```
|
||||
|
||||
The comparator reports `Identical gameplay snapshots across 1889 simulation
|
||||
@@ -12,9 +12,9 @@ Run it with:
|
||||
RAPTOR_TEST_DATA=/absolute/path/to/data cargo test --release --no-default-features --test first_mission -- --ignored --nocapture
|
||||
```
|
||||
|
||||
Without `RAPTOR_TEST_DATA`, it reads this checkout's `data/` directory. The
|
||||
Without `RAPTOR_TEST_DATA`, it reads this checkout's `../data/` directory. The
|
||||
test is ignored in the default suite because original game data is not shipped
|
||||
in Git. It writes local results to `.reference/`, which is also ignored.
|
||||
in Git. It writes local results to `../.reference/`, which is also ignored.
|
||||
|
||||
## Recorded results
|
||||
|
||||
@@ -75,7 +75,7 @@ difficulty, input-device usability, graphics quality, or audio accuracy.
|
||||
|
||||
For each difficulty, the test generates:
|
||||
|
||||
- `.reference/first-mission-fresh-difficulty-N.dem`: the original 12-byte demo
|
||||
- `../.reference/first-mission-fresh-difficulty-N.dem`: the original 12-byte demo
|
||||
record layout, with a sector/wave header, button bytes, observed player
|
||||
position and bank. It includes the complete boss encounter and ends at the
|
||||
flyby cue, before stats-stage forced departure movement: 4,603 and 4,723
|
||||
@@ -1,17 +1,17 @@
|
||||
# Optional HD artwork
|
||||
|
||||
The Rust Options screen includes **HD art**. It starts disabled. Enable it to use reviewed artwork from `data/hd/hd.json`; each missing or rejected frame keeps the selected original / 2x / 3x / 4x crisp treatment. The scale setting still determines the indexed rendering resolution, and the HD toggle can be changed while paused. HD art is presentation only: simulation, collision sizes, banking positions and save content IDs stay unchanged.
|
||||
The Rust Options screen includes **HD art**. It starts disabled. Enable it to use reviewed artwork from `../data/hd/hd.json`; each missing or rejected frame keeps the selected original / 2x / 3x / 4x crisp treatment. The scale setting still determines the indexed rendering resolution, and the HD toggle can be changed while paused. HD art is presentation only: simulation, collision sizes, banking positions and save content IDs stay unchanged.
|
||||
|
||||
The current local proof covers **the light player ship's straight banking frame only** (`0x1011d`, frame 3 of 7). The other six frames, the dark-sector ship, enemies, projectiles and terrain retain original art. Switching into a bank therefore changes visual style. This proof is suitable for evaluating the look; it is not a finished remaster. Original and generated game pixels are excluded from Git.
|
||||
The current local base-game proof covers **the light player ship's straight banking frame only** (`0x1011d`, frame 3 of 7). The other six frames, the dark-sector ship, enemies, projectiles and terrain retain original art. Switching into a bank therefore changes visual style. This proof is suitable for evaluating the look; it is not a finished remaster. Original pixels and this base-game proof remain outside Git. The separate authored mod packages include their generated SD/HD PNGs, sounds and provenance in Git.
|
||||
|
||||
The source was decoded with `tools/hd_art_source.py`, inspected, and passed to the **built-in image_gen tool** using the imagegen skill. The optional proof and its exact generation prompt are saved locally at:
|
||||
|
||||
- `data/hd/light-player-straight-hd-v1.png`
|
||||
- `data/hd/prompts/light-player-straight-v1.txt`
|
||||
- `data/hd/provenance.json`
|
||||
- `data/hd/source/light-player-straight.png`
|
||||
- `../data/hd/light-player-straight-hd-v1.png`
|
||||
- `../data/hd/prompts/light-player-straight-v1.txt`
|
||||
- `../data/hd/provenance.json`
|
||||
- `../data/hd/source/light-player-straight.png`
|
||||
|
||||
The PNG has real alpha transparency, is 1254x1254, and was copied unchanged from the tool's output. At the original 32x32 logical resolution, its visible alpha footprint overlaps the source by 92.1% intersection-over-union; its bounds are `(3,0)..(29,31)` against `(2,0)..(29,31)` for the original. The nose, wing layout, silver/gunmetal body and dark red accents remain recognizable, but panel detail and some contours differ. Further artistic review and a complete, consistent banking sequence are required before enabling HD art by default. An additional extreme-bank attempt is saved as `data/hd/light-player-bank-0-hd-v1.png` with `prompts/light-player-bank-0-v1.txt`, but is excluded from the active pack because its footprint overlap is only 62.2% and its engine ends are shortened. The original extreme-bank sprite continues to render.
|
||||
The PNG has real alpha transparency, is 1254x1254, and was copied unchanged from the tool's output. At the original 32x32 logical resolution, its visible alpha footprint overlaps the source by 92.1% intersection-over-union; its bounds are `(3,0)..(29,31)` against `(2,0)..(29,31)` for the original. The nose, wing layout, silver/gunmetal body and dark red accents remain recognizable, but panel detail and some contours differ. Further artistic review and a complete, consistent banking sequence are required before enabling HD art by default. An additional extreme-bank attempt is saved as `../data/hd/light-player-bank-0-hd-v1.png` with `prompts/light-player-bank-0-v1.txt`, but is excluded from the active pack because its footprint overlap is only 62.2% and its engine ends are shortened. The original extreme-bank sprite continues to render.
|
||||
|
||||
## Pack format
|
||||
|
||||
@@ -54,7 +54,7 @@ Use the existing catalog decoder to prepare a transparent reference without redr
|
||||
|
||||
```sh
|
||||
python3 tools/hd_art_source.py --asset 1011d \
|
||||
--output data/hd/source/light-player-straight.png --preview-scale 16
|
||||
--output ../data/hd/source/light-player-straight.png --preview-scale 16
|
||||
```
|
||||
|
||||
Inspect every source frame before generating its replacement. Request the same orthographic camera, silhouette, canvas placement, orientation, material colors and lighting for every frame. Preserve the generated alpha. Do not substitute rotations of one frame for the original bank poses: compare the complete sequence at its logical size and at the intended display resolution. Verify that the nose, engine exits, wing extremes and animation pivots remain aligned and that no clipping or background halos appear.
|
||||
@@ -1,9 +1,11 @@
|
||||
# Iron Coast content packages
|
||||
|
||||
Iron Coast is a local campaign assembled from seven independently toggleable
|
||||
mods. Enable all six dependencies before enabling the campaign package. The
|
||||
Mods manager validates versions and dependency order and applies the change
|
||||
at the main menu. The new weapons can also be used in the original campaigns;
|
||||
mods. Enabling the mission package checks and selects its six installed
|
||||
dependencies automatically. Disabling it also deselects unused dependencies
|
||||
after a confirmation listing the affected packages. Dependencies still needed
|
||||
by another enabled mod remain selected. The Mods manager validates versions
|
||||
and dependency order and applies the change at the main menu. The new weapons can also be used in the original campaigns;
|
||||
the enemy packages can be referenced from other missions.
|
||||
|
||||
| Package | Content |
|
||||
@@ -29,15 +31,16 @@ turrets and the command ship to finish. The boss stays in the playfield until
|
||||
killed; waiting out the mission duration cannot produce victory.
|
||||
|
||||
When inventory space allows, the mission grants a trial Pulse Cannon, which
|
||||
fires alongside forward guns, and three field repairs. Granted equipment
|
||||
remains with the pilot. A full inventory can still start; new grants are
|
||||
fires alongside forward guns, and three field repairs. The cannon is a mission-only loan and is returned before a successful flight
|
||||
is saved; a cannon already owned by the pilot remains untouched. A full inventory can still start; new grants are
|
||||
skipped while existing equipment is preserved. Cycle equipment to **Iron Coast Field Repair** and
|
||||
press the special button to restore 25 shield per repair. Depots drop extra
|
||||
repairs. Victory pays 5,000 credits plus ordinary enemy rewards. The central
|
||||
turrets and boss patrol overlap the starter-gun firing corridor; the mission
|
||||
is intended to remain playable without the trial weapon.
|
||||
|
||||
Script objectives are namespaced and saved with the pilot:
|
||||
Script objectives are namespaced and tracked for the current flight. Script
|
||||
state and completed mission IDs are saved with the pilot:
|
||||
|
||||
| Objective | Meaning |
|
||||
| --- | --- |
|
||||
@@ -47,7 +50,7 @@ Script objectives are namespaced and saved with the pilot:
|
||||
| `iron_coast_boss:defeated` | Command ships destroyed |
|
||||
| `iron_coast_mission_1:depots_opened` | Supply depots destroyed |
|
||||
| `iron_coast_mission_1:complete` | All required targets destroyed |
|
||||
| `iron_coast_mission_1:trial_issued` | Trial weapon was granted or replenished |
|
||||
| `iron_coast_mission_1:trial_issued` | A loan or an already owned cannon is available |
|
||||
|
||||
## Art and audio
|
||||
|
||||
@@ -88,8 +91,8 @@ required locally to play the game and remains excluded from version control.
|
||||
To rebuild the mission assets from their included generated masters, run:
|
||||
|
||||
```sh
|
||||
python3 examples/mods/iron_coast_mission_1/build_assets.py --palette data/misc/PALETTE_DAT
|
||||
cargo run --no-default-features -- --mods examples/mods --validate-mods iron_coast_scout,iron_coast_turret,iron_coast_boss,pulse_cannon,seeker_swarm,ion_lance,iron_coast_mission_1
|
||||
python3 mods/iron_coast_mission_1/build_assets.py --palette ../data/misc/PALETTE_DAT
|
||||
cargo run --no-default-features -- --mods mods --validate-mods iron_coast_scout,iron_coast_turret,iron_coast_boss,pulse_cannon,seeker_swarm,ion_lance,iron_coast_mission_1
|
||||
```
|
||||
|
||||
## Acceptance checks
|
||||
@@ -102,10 +105,12 @@ and the trial Pulse Cannon. These tests use no original images and replace the
|
||||
generated assets with synthetic fixtures. Local package validation additionally checks
|
||||
the actual generated SD/HD images and WAV files.
|
||||
|
||||
Release acceptance passes all six tests in **1.43 seconds**. Synthetic
|
||||
seven-package activation takes 0.179–0.290 seconds including fixture creation
|
||||
and PNG/WAV validation. Actual seven-package validation, including the generated
|
||||
SD/HD artwork and WAV files, passes in **2.234 seconds** with zero overrides.
|
||||
Release acceptance passes all eight tests in **1.20 seconds**. The tests also
|
||||
check loan cleanup after victory, retention of an owned cannon, and starting
|
||||
with a full inventory including stacked super-shields. Synthetic seven-package
|
||||
activation takes 0.173–0.294 seconds including fixture creation and PNG/WAV
|
||||
validation. Local package validation also checks the generated SD/HD artwork
|
||||
and WAV files, with zero overrides.
|
||||
The two playable runs complete as follows:
|
||||
|
||||
| Loadout | Completion step | Final shield | Credits |
|
||||
@@ -122,11 +127,7 @@ enemy damage commands or victory-objective mutations. They establish that
|
||||
the actual waves and boss can be completed under this controlled input, not
|
||||
that every normal-player route or loadout has been balanced.
|
||||
|
||||
The default debug suite took 34.15 seconds for the earlier five-test version;
|
||||
the release result shows that its slowdown comes mainly from unoptimized
|
||||
simulation, serialization and scripting. PNG color memoization reduced the
|
||||
previous multi-minute asset validation overhead. Release measurements above
|
||||
exclude compilation.
|
||||
Release measurements exclude compilation.
|
||||
|
||||
Visual approval remains provisional: sprite and terrain previews were
|
||||
inspected for readability, canvas alignment and transparency, with numeric
|
||||
@@ -4,24 +4,24 @@ This is an experimental API for the Rust engine. It provides local content packa
|
||||
|
||||
## Try the example
|
||||
|
||||
`examples/mods/aurora/` adds two projectiles, a pulse cannon, a repair cell, two enemies, a mission and a campaign. The weapon adds angled shots in Rhai; enemy movement, item rewards and mission objectives also use scripts. Its artwork references asset IDs in the locally extracted original catalog. The example contains no original or generated game artwork.
|
||||
`mods/aurora/` adds two projectiles, a pulse cannon, a repair cell, two enemies, a mission and a campaign. The weapon adds angled shots in Rhai; enemy movement, item rewards and mission objectives also use scripts. Its artwork references asset IDs in the locally extracted original catalog. The example contains no original or generated game artwork.
|
||||
|
||||
Validate the package against your original game data:
|
||||
|
||||
```sh
|
||||
cargo run --no-default-features -- --data data --mods examples/mods --validate-mods aurora
|
||||
cargo run --no-default-features -- --data ../data --mods mods --validate-mods aurora
|
||||
```
|
||||
|
||||
Run its mission without a window:
|
||||
|
||||
```sh
|
||||
cargo run --no-default-features -- --data data --mods examples/mods \
|
||||
cargo run --no-default-features -- --data ../data --mods mods \
|
||||
--enabled aurora --headless aurora:field_trials --ticks 700
|
||||
```
|
||||
|
||||
For the in-game manager, copy `examples/mods/aurora` into the `mods/` directory under `$XDG_DATA_HOME/RaptorReplica` (default `~/.local/share/RaptorReplica/mods/`), or start the Rust engine with `--mods examples/mods`. Open **Mods**, toggle Aurora, then select **Apply selections**. Select its mission from the mission menu. Existing pilots can add mods while preserving required versions, hashes and relative load order; the next save records the expanded active set. Disabling, changing or reordering required mods blocks loading with details. Use another pilot for an incompatible set.
|
||||
The manager discovers the bundled `mods/` folder by default when no user mods folder exists. You can also copy `mods/aurora` into the `mods/` directory under `$XDG_DATA_HOME/RaptorReplica` (default `~/.local/share/RaptorReplica/mods/`), or start the Rust engine with `--mods mods`. Open **Mods**, toggle Aurora, then select **Apply selections**. Select its mission from the mission menu. Existing pilots can add mods while preserving required versions, hashes and relative load order; the next save records the expanded active set. Disabling, changing or reordering required mods blocks loading with details. Use another pilot for an incompatible set.
|
||||
|
||||
In the Mods screen, Enter toggles a package or activates the selected action. Rescan after editing a package on disk. Load dependencies before dependents; independent packages retain your chosen priority. Later explicit overrides win. Changes made through the pause menu remain pending until the main menu. Candidate registries and scripts are validated before the active set changes.
|
||||
In the Mods screen, Enter toggles a package or activates the selected action. Enabling a package immediately checks versions, API compatibility, cycles and conflicts, then selects its installed dependencies recursively. A failed check leaves the selection unchanged. Disabling includes dependent mods and dependencies that become unused, preserving dependencies required by other remaining packages. A single-package disable toggles immediately; changes affecting multiple packages show an **Are you sure?** popup listing every affected mod, with Cancel selected initially. Cancel or Back preserves the pending selection. Rescan after editing a package on disk. Dependencies load before dependents; independent packages retain your chosen priority. Later explicit overrides win. Changes made through the pause menu remain pending until the main menu. Candidate registries and scripts are validated before the active set changes.
|
||||
|
||||
## Package layout and manifest
|
||||
|
||||
@@ -50,7 +50,7 @@ conflicts = ["alternate_aurora"]
|
||||
common_tools = "^1.2"
|
||||
```
|
||||
|
||||
IDs use lowercase ASCII letters, digits, `_` and `-`, with a maximum of 64 bytes. `base` is reserved. Package versions and dependency requirements use semantic version syntax. Dependencies must be explicitly enabled; the loader will not quietly enable or install them. Cycles, missing packages, unsupported API versions, incompatible dependency versions and declared conflicts reject activation. Two installed folders claiming the same ID make that ID unusable; rename or remove one folder, then rescan.
|
||||
IDs use lowercase ASCII letters, digits, `_` and `-`, with a maximum of 64 bytes. `base` is reserved. Package versions and dependency requirements use semantic version syntax. The in-game manager selects compatible installed dependencies when enabling a package. It never downloads or installs missing packages. The CLI still requires a complete explicit `--enabled` set. Cycles, missing packages, unsupported API versions, incompatible dependency versions and declared conflicts reject activation. Two installed folders claiming the same ID make that ID unusable; rename or remove one folder, then rescan.
|
||||
|
||||
All package paths are relative. Absolute paths, parent traversal, symlinks and special files are rejected. Packages are limited to 10,000 files, 16 directory levels, 64 MiB per file and 256 MiB in total. Manifests are limited to 64 KiB; display names to 128 bytes; descriptions to 4 KiB; script declarations to 64, with a 1 MiB limit per source file. Every file, including artwork and documentation, contributes to the package SHA-256 hash. A package changed after discovery requires rescanning before it can be applied.
|
||||
|
||||
@@ -58,6 +58,14 @@ All package paths are relative. Absolute paths, parent traversal, symlinks and s
|
||||
|
||||
`content.json` has optional `weapons`, `items`, `enemies`, `missions`, `campaigns`, `sounds` and `overrides` arrays. Unknown fields are rejected. IDs have the form `namespace:name`, for example `aurora:pulse_cannon`. IDs are stable save references and unique across content types. Keep item and projectile IDs distinct: the item `aurora:pulse_cannon` refers to the weapon/projectile `aurora:pulse_projectile` through its `weapon` property.
|
||||
|
||||
Items may include an optional `description` of up to 4096 UTF-8 bytes for shop information. The shop displays the description, artwork, effective target types, firing mode, price, ownership and inventory limits.
|
||||
|
||||
The item price buys `initial_count` units, up to its capacity. Selling an
|
||||
ordinary item removes one unit and returns half its unit purchase price,
|
||||
rounded down. Original energy refills and super-shield modules retain their
|
||||
half-price sale per refill/module. This prevents multi-unit mod packs from
|
||||
creating credits through repeated buying and selling.
|
||||
|
||||
New definitions must belong to the package namespace. An existing definition may be replaced only when its ID appears in `overrides` and the replacement retains the same content type. Overrides are complete replacements, not field merges. An override targeting a missing ID, a replacement without explicit permission, an override without its replacement, or duplicate IDs within a pack rejects the whole pack. The manager exposes the override history and its winning owner.
|
||||
|
||||
```json
|
||||
@@ -152,6 +160,15 @@ Commands apply only after a callback returns and passes validation. If a callbac
|
||||
|
||||
## Commands
|
||||
|
||||
The 20-slot inventory limit counts physical super-shield modules separately.
|
||||
`player.super_shield_reserves` lists the stored charge of reserve modules;
|
||||
`player.inventory["base:super_shield"]` is the equipped module's charge.
|
||||
For the built-in `base:energy` and `base:super_shield`, `give_item` and
|
||||
`consume_item` change charge units, not the number of modules. Zero-charge
|
||||
shield entries remain valid. Other items are removed when their quantity
|
||||
reaches zero, releasing their slot and selecting another available special
|
||||
item when needed.
|
||||
|
||||
Use the `op` field shown below. All fields listed are required unless stated otherwise. Entity zero identifies the player for damage; movement commands currently address enemies.
|
||||
|
||||
| `op` | Fields | Effect |
|
||||
@@ -0,0 +1,41 @@
|
||||
# Desktop display measurements
|
||||
|
||||
Local release measurements on 2026-10-10 used SDL's OpenGL renderer at
|
||||
1920×1080 fullscreen output, aspect correction, Scale4, no scanlines, and all seven Iron Coast
|
||||
packages. They include normal terrain, sprites, indexed shadows, effects and
|
||||
mod scripting. They exclude Cargo compilation.
|
||||
|
||||
| Mode | Startup | Render work median | Render work 95th percentile | Frame median | Frame 95th percentile |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: |
|
||||
| SD artwork | 2,345.82 ms | 7.40 ms | 8.76 ms | 7.52 ms | 8.88 ms |
|
||||
| HD artwork | 2,375.56 ms | 8.67 ms | 14.66 ms | 8.79 ms | 14.78 ms |
|
||||
|
||||
Each run sampled 174 frames from a 180-frame flight, excluding five warmup
|
||||
frames and the screenshot frame. Work time excludes the presentation call;
|
||||
frame time includes it. Startup covers desktop-host construction and SDL setup;
|
||||
the preceding CLI catalog registration is excluded. The explicit one-millisecond smoke-loop sleep is
|
||||
outside both measurements. These short runs establish local performance for
|
||||
this scene and machine, not worst-case performance across every boss or device.
|
||||
The fixed 70/3 Hz simulation advances independently of display timing.
|
||||
|
||||
From `RustRaptor/`, prepare two isolated profile configurations with
|
||||
`width = 1920`, `height = 1080`, `fullscreen = true`, `scale = 4`, `scanlines = false`, and
|
||||
`hd_mode = false` or `true`. Enable the mission's six dependencies and mission
|
||||
package in `enabled_mods`; see [Iron Coast](iron-coast.md). Run:
|
||||
|
||||
```sh
|
||||
./run.sh --profile-root ../.reference/enemy-sd-profile \
|
||||
--preview-mission iron_coast_mission_1:mission_01 \
|
||||
--smoke-frames 180 --benchmark \
|
||||
--screenshot ../.reference/rustraptor-sd-1080-final.png
|
||||
./run.sh --profile-root ../.reference/enemy-hd-profile \
|
||||
--preview-mission iron_coast_mission_1:mission_01 \
|
||||
--smoke-frames 180 --benchmark \
|
||||
--screenshot ../.reference/rustraptor-hd-1080-final.png
|
||||
```
|
||||
|
||||
Both captures were checked to be exactly 1920×1080. The benchmark reports the
|
||||
actual SDL output size, since a window manager can constrain a requested window.
|
||||
Use a real SDL display. Dummy-video screenshots verify raster composition but
|
||||
cannot measure GPU presentation. Frame-limited runs do not save pilots or
|
||||
settings. Profiles, caches and screenshots remain ignored local files.
|
||||
@@ -0,0 +1,101 @@
|
||||
# Rust engine and validation
|
||||
|
||||
Rust is the default engine. The Rust binary never calls or embeds the C++ engine. SDL2 provides window/input/controller/audio services. Simulation and the validation CLI build without SDL2. The retained C++ checkout is optional reference material.
|
||||
|
||||
| Module | Responsibility |
|
||||
| --- | --- |
|
||||
| assets | Checked catalog, palettes, raw/span pictures, libraries, maps and demo records. |
|
||||
| content, legacy_tables | Typed registries and generated original numeric mappings. |
|
||||
| simulation | Rational clock, integer motion, shared RNG, collision/weapon/enemy/terrain rules, script transactions. |
|
||||
| render, hd | Indexed canvas, ScaleNx, caches, PNG/palette conversion and optional source-hashed HD art. |
|
||||
| audio, sound | Original MUS/GENMIDI FM and digital DSP behavior; package-local PCM WAV decoding. |
|
||||
| cinematics | Checked AGX delta frames and movie timing. |
|
||||
| persistence | TOML settings, versioned JSON pilots, atomic writes and read-only legacy import. |
|
||||
| modding | Packages, dependency ordering, overrides, bounded Rhai callbacks/state and save pins. |
|
||||
| desktop | SDL2 services, UI, shop/equipment, mod manager, settings and interpolation. |
|
||||
|
||||
## Build and run
|
||||
|
||||
Rust 1.88+, Cargo and SDL2 development libraries are required. A local SDL2 installation in `~/.local/lib` is supported. Commands below run from `RustRaptor/`. The launcher sets the library path and uses a release build:
|
||||
|
||||
```sh
|
||||
./run.sh
|
||||
./run.sh --mods mods
|
||||
```
|
||||
|
||||
For development and tests:
|
||||
|
||||
```sh
|
||||
export LD_LIBRARY_PATH="$HOME/.local/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
cargo test --locked
|
||||
cargo test --locked --no-default-features
|
||||
RAPTOR_TEST_DATA="$PWD/../data" cargo test --locked
|
||||
RAPTOR_TEST_DATA="$PWD/../data" cargo test --locked -- --ignored
|
||||
```
|
||||
|
||||
Portable fixtures use synthetic assets and the bundled authored mod art/audio. Original integration checks are opt-in and local. Native audio comparisons compile a small retained-source harness with g++ and SDL2 headers; pure Rust playback itself uses no C++ runtime.
|
||||
|
||||
## Profiles and settings
|
||||
|
||||
Rust uses `$XDG_DATA_HOME/RaptorReplica/pilot-NNNN.json` and `mods/`, `$XDG_CONFIG_HOME/RaptorReplica/config.toml`, and `$XDG_CACHE_HOME/RaptorReplica/` for derived assets. Normal XDG defaults apply. Pilots record active package versions/hashes and script state/RNG. Missing or changed requirements block loading, without deleting equipment or replacing the save.
|
||||
|
||||
Legacy `~/.local/share/Raptor/SETUP.INI` and pilot files are imported read-only. All difficulties, waves, portrait and training metadata are retained. Rust writes only its separate versioned files. Explicit CLI import output cannot be the original file.
|
||||
|
||||
Options include scaling, scanlines, aspect correction, fullscreen/borderless, input bindings/controller, volumes and optional HD art. New/load pilot controls keep incompatible save slots separate. The Mods screen applies validated selections at the main menu; selections made during flight remain pending until returning there.
|
||||
|
||||
The main menu leads to the Hangar, new/load/import pilots, options, mods and
|
||||
extras. The Hangar keeps flying, mission selection, the supply room, inventory,
|
||||
**Save pilot**, pilot ID editing and exit visible together. Saving writes the
|
||||
pilot atomically and shows the callsign and slot. Completed missions and
|
||||
equipment purchases also save automatically. Saves contain hangar/progression
|
||||
state; an in-flight save does not create a mid-mission checkpoint.
|
||||
New pilot registration selects a name, callsign, ID picture and difficulty,
|
||||
and starts with the original 10,000 credits and 75 energy. Imported ID pictures
|
||||
retain their native catalog identity.
|
||||
|
||||
Keyboard defaults are arrows for movement, Ctrl for firing, Space for bombs,
|
||||
Alt or Shift for cycling equipment, and Z for selected consumables. Selecting
|
||||
a weapon makes the fire control fire it alongside the forward guns. Settings
|
||||
that retain the old complete default cycle/bomb/special binding combination
|
||||
migrate on load; custom combinations are preserved.
|
||||
|
||||
## Local asset and platform checks
|
||||
|
||||
```sh
|
||||
cargo run --locked --no-default-features -- --data ../data --verify-assets
|
||||
cargo run --locked --no-default-features -- --data ../data --mods mods --validate-mods aurora
|
||||
cargo run --locked --no-default-features -- --data ../data --mods mods \
|
||||
--enabled aurora --headless aurora:field_trials --ticks 700
|
||||
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy cargo run --locked -- \
|
||||
--data ../data --profile-root ../.reference/smoke --smoke-frames 5 \
|
||||
--screenshot ../.reference/menu.png
|
||||
```
|
||||
|
||||
Use real SDL video for interactive/display-performance checks. Dummy screenshots verify raster placement, not GPU/vsync performance. `--preview-mission ID` starts a mission; `--preview-cinematic intro|landing|death|end1|end2|end3` previews movies. Frame-limited runs do not save pilots/settings; cache stays within the selected profile.
|
||||
|
||||
## Controlled reference replays
|
||||
|
||||
This optional comparison workflow uses the retained C++ source. Rebuild it before recording. Trace output is opt-in during legacy demo playback and records complete updates after palette/stat processing, which also consumes the shared RNG.
|
||||
|
||||
```sh
|
||||
mkdir -p ../.reference
|
||||
cmake --build ../raptor/build --target raptor --parallel 8
|
||||
(cd ../data && env SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
||||
XDG_DATA_HOME="$PWD/../.reference/legacy-profile" \
|
||||
RAPTOR_REFERENCE_TRACE="$PWD/../.reference/cpp-demo.jsonl" \
|
||||
RAPTOR_REFERENCE_TICKS=1889 \
|
||||
../raptor/build/bin/raptor PLAY "$PWD/demos/DEMO1G1_REC")
|
||||
cargo run --locked --no-default-features -- --data ../data \
|
||||
--replay DEMO1G1_REC --ticks 1889 --trace ../.reference/rust-demo.jsonl
|
||||
python3 tools/compare_replays.py ../.reference/cpp-demo.jsonl ../.reference/rust-demo.jsonl
|
||||
```
|
||||
|
||||
All 1,889 available steps of DEMO1G1_REC match the captured fields: RNG, player coordinates/bank/shields/credits, ordered enemy position/health/animation/path state and ordered projectile assets/positions. The comparator fails at first divergence or unequal lengths. This is a subset of full state; inventory, effects, objectives and internal AI counters are outside this trace. That demo starts sector 1 wave 3 and ends before its boss. See the separate [first-mission wins](first-mission-validation.md), [108 campaign runs](campaign-validation.md) and [departure/death checks](transition-validation.md). Recordings stay ignored in `../.reference/`.
|
||||
|
||||
## Audio and remaining acceptance
|
||||
|
||||
The Rust FM/DSP implementation has synthetic sample-by-sample native comparisons and a four-second original intro-music comparison at 44.1kHz. The checked sound bank also dispatches original and mod cues through the SDL callback; real-device output checks are documented in [sound validation](sound-validation.md). These establish those cases, not every track/input/output rate. The Rust core retains the original envelope/noise semantics and LGPL source provenance.
|
||||
|
||||
The campaign checks cover all waves and difficulties with assistance, and first-mission tests win without replenishing pilot health or editing enemy state. Wider ordinary playtesting and more complete native state comparisons remain useful. Original cinematics decode/play locally; exact fade/transition/custom-palette fidelity has limited comparison coverage. Some menu layouts differ. Base-game HD coverage is partial; bundled mods supply SD/HD art. See [display measurements](performance.md).
|
||||
|
||||
Scale2x/3x follows the [published algorithm](https://www.scale2x.it/algorithm); Scale4x applies Scale2x twice. WAV parsing follows the [RIFF chunk format](https://learn.microsoft.com/en-us/windows/win32/xaudio2/resource-interchange-file-format--riff-). Original catalog/reference assets remain outside version control. Authored mod artwork and sounds are tracked.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Sound playback validation
|
||||
|
||||
The Rust engine plays original digital effects, MUS music through its Rust FM
|
||||
synthesizer, and package-local WAV cues. SDL2 provides the output device.
|
||||
|
||||
Original sound-event IDs identify an empty catalog marker. The actual digital
|
||||
patch is four catalog entries later, matching the original setup routine.
|
||||
The sound bank resolves and checks that patch, preloads the 26 original
|
||||
digital assets, and reports missing or invalid cues. Mod WAVs are decoded and
|
||||
cached before acquiring the audio-device lock. Successful mod activation
|
||||
invalidates that cache.
|
||||
|
||||
Music/effect gains and channel limits are applied before the device starts.
|
||||
Changing effect volume updates playing voices; muting clears held samples.
|
||||
Music volume zero gates FM output while the score and synthesizer continue
|
||||
advancing, so restoring volume resumes the current music position.
|
||||
|
||||
Portable audio and sound-bank tests cover checked decoding, mixing, pitch,
|
||||
priority, channel limits, gains, mute behavior and missing/invalid assets.
|
||||
Optional original-data checks compare FM and digital samples with a small
|
||||
retained-source harness. Another integration check dispatches all 36 original
|
||||
cue variants through the production Rust SDL callback and checks their output.
|
||||
|
||||
Local real-device checks on 2026-10-10 used SDL's PulseAudio backend through
|
||||
PipeWire to the default analog stereo sink. A first-mission run with music
|
||||
muted produced digital-effect output with peak 16,390 and RMS 6,657.51. A
|
||||
concurrent sink-monitor recording correlated with the callback output at
|
||||
0.99929. A seven-package Iron Coast run also produced audible-level output
|
||||
(peak 16,406; RMS 4,909.62). System volume and mute were unchanged. These
|
||||
measurements confirm output routing and signal; they do not assess acoustic
|
||||
balance on every speaker or every cue during ordinary play.
|
||||
|
||||
The final combined build was checked through the same real device after the
|
||||
mute fix: 172,544 captured stereo frames of first-mission effects had peak
|
||||
16,384 and RMS 6,506.91. A separate run with both gains at zero captured
|
||||
54,784 stereo frames with zero nonzero samples, peak zero and RMS zero.
|
||||
|
||||
For a bounded diagnostic capture of the actual production callback, run from
|
||||
`RustRaptor/` with an isolated profile:
|
||||
|
||||
```sh
|
||||
RAPTOR_AUDIO_CAPTURE="$PWD/../.reference/audio.wav" \
|
||||
RAPTOR_AUDIO_CAPTURE_SECONDS=10 \
|
||||
SDL_AUDIODRIVER=pulseaudio ./run.sh \
|
||||
--profile-root ../.reference/audio-profile \
|
||||
--preview-mission base:sector_1_wave_1 --smoke-frames 540
|
||||
```
|
||||
|
||||
The capture is PCM16 stereo and accepts 1–120 seconds. Configure music and
|
||||
effects in that profile before capture. Original assets, captures and reports
|
||||
remain ignored under `../data/` and `../.reference/`. Authored mod WAVs and
|
||||
their synthesis recipes are tracked in Git.
|
||||
@@ -74,10 +74,10 @@ captured pre-ending behavior; it does not validate the new transition itself.
|
||||
See [campaign-validation.md](campaign-validation.md) for reference rebuild and
|
||||
comparison commands, captured fields, original-data checks and limitations.
|
||||
|
||||
The relevant retained sources are `raptor/src/rap.cpp` (`RAP_ThinkStats` and
|
||||
`Do_Game`), `raptor/src/rap.h` (`END_DURATION`, `END_EXPLODE`, `END_FLYOFF`),
|
||||
`raptor/src/input.cpp` (`IPT_MovePlayer`, `IPT_FMovePlayer`),
|
||||
`raptor/src/enemy.cpp` (`ENEMY_Remove`) and `raptor/src/objects.cpp`
|
||||
The relevant retained sources are `../raptor/src/rap.cpp` (`RAP_ThinkStats` and
|
||||
`Do_Game`), `../raptor/src/rap.h` (`END_DURATION`, `END_EXPLODE`, `END_FLYOFF`),
|
||||
`../raptor/src/input.cpp` (`IPT_MovePlayer`, `IPT_FMovePlayer`),
|
||||
`../raptor/src/enemy.cpp` (`ENEMY_Remove`) and `../raptor/src/objects.cpp`
|
||||
(`OBJS_SubEnergy`). God-mode/debug behavior, rumble, warning-light presentation,
|
||||
cinematic sequencing and a native transition reference are outside this scoped
|
||||
verification.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Sprite and terrain validation
|
||||
|
||||
`tests/visuals.rs` separates portable synthetic checks from local checks of the original catalog. Generated contact sheets and original pixels stay under ignored `.reference/visuals/`; they are not shipped with the engine or committed.
|
||||
`tests/visuals.rs` separates portable synthetic checks from local checks of the original catalog. Generated contact sheets and original pixels stay under ignored `../.reference/visuals/`; they are not shipped with the engine or committed.
|
||||
|
||||
The independent test oracle follows the unoptimized corner rules in the [published Scale2x/Scale3x algorithm specification](https://www.scale2x.it/algorithm), with its clamped border sampling. Scale4x applies the independent Scale2x oracle twice. The renderer uses a shared optimized guard, so the oracle and renderer express the rules differently.
|
||||
|
||||
@@ -21,7 +21,7 @@ cargo test --test visuals original_shadow_tables_and_banking_masks_match_indexed
|
||||
|
||||
The local checks cover all seven light, dark and firing-flash player banking frames; all 42 `GEXPLO_BLK` ground explosion frames; all 16 `AIRBOOM_PIC` and 13 `EXPLO2_BLK` frames; four micro-missile and gun-ejecta frames; six `SHIP22G1_PIC` boss frames and four `SHIP08G1_PIC` enemy frames. Each original frame is compared against the oracle at 1×, 2×, 3× and 4×, with exact logical canvas dimensions and original palette labels retained. The report records frame IDs, logical canvases, full-canvas center anchors and visible bounds at every scale.
|
||||
|
||||
The original 20-byte GFX header contains type, two option fields, width and height; its option fields are not replacement x/y origins. Span x/y coordinates locate pixels within the unchanged canvas. Player rendering uses that top-left canvas origin. Original centered effects use half the full canvas width/height, as recorded by `ANIMS_Register` in `raptor/src/anims.cpp`; visible explosion bounds must not become animation anchors. Missing transparent margins or auto-cropping frames would move those anchors.
|
||||
The original 20-byte GFX header contains type, two option fields, width and height; its option fields are not replacement x/y origins. Span x/y coordinates locate pixels within the unchanged canvas. Player rendering uses that top-left canvas origin. Original centered effects use half the full canvas width/height, as recorded by `ANIMS_Register` in `../raptor/src/anims.cpp`; visible explosion bounds must not become animation anchors. Missing transparent margins or auto-cropping frames would move those anchors.
|
||||
|
||||
A three-by-three patch from the first original mission is composed at native resolution and filtered as one image. The center tile filtered with two original pixels of neighboring context must exactly match the center of the full joined patch at 2×, 3× and 4×. The renderer's two-pixel terrain gutter covers Scale4x's two successive passes. This establishes filter consistency across the tested boundaries; it does not assess whether different source tiles were artistically seamless.
|
||||
|
||||
@@ -52,6 +52,6 @@ The original terrain patch exposed 113 differing pixels at 2×, 297 at 3× and 7
|
||||
|
||||
The optional HD player proof remains a separate review: it replaces only straight flight, so banking still changes visual style. The generated extreme-bank attempt remains excluded because it shortened the engines and failed the footprint check; crisp original fallback is retained for that frame.
|
||||
|
||||
The frontend previously requested `AIRMED_BLK` for effects, but that name does not exist in the original catalog. Actual original sequences include `AIRBOOM_PIC`, `GEXPLO_BLK`, `EXPLO2_BLK`, flak and sparks. This finding was reported to the engine owner. A generic explosion sequence repairs the visible fallback, but full effect identity, duration, layer, origin and update parity require separate comparison with the C++ animation system.
|
||||
The frontend previously requested `AIRMED_BLK`, which does not exist in the original catalog. Effects now carry typed identities for the original air/ground explosions, flak, energy, people, flares and sparkles. The renderer selects each sequence's asset, duration, centered canvas origin and ground/air layer. Enemy deaths retain their original multiple bursts and RNG consumption; ground effects follow terrain scroll. This source-based port repairs the missing sequence and generic fallback. Exhaustive visual comparison of every effect remains outside the sampled checks above.
|
||||
|
||||
The new enemy packages include their generated SD/HD artwork and audio in Git. Their original style-reference pixels under `art/source/` remain excluded. Their per-package `art-qa.json` and `provenance.json` provide a separate record of supplied-art canvas alignment and generation prompts.
|
||||
@@ -0,0 +1,107 @@
|
||||
# Shipped weapon prices and balance
|
||||
|
||||
The three independent weapon mods use the original game's credit scale. Their
|
||||
initial example prices of 6,500, 14,000 and 22,000 made reusable upgrades cheaper
|
||||
than much weaker original equipment. The revised prices preserve their firing,
|
||||
damage, scripts, sounds and artwork.
|
||||
|
||||
| Mod weapon | Price | Place in the original progression |
|
||||
| --- | ---: | --- |
|
||||
| Pulse Cannon | 185,000 | Just above the 175,600-credit Micro Missile primary upgrade. It adds similar sustained damage and also adds a spread burst every third volley. |
|
||||
| Seeker Swarm | 285,000 | Above the 250,650-credit Mini Gun. Its three missiles track air and ground enemies and hits fragment into at most two nearby enemies. It remains below the 512,850-credit instant Turret. |
|
||||
| Ion Lance | 425,000 | Below the Turret and the 950,000-credit Death Ray. Its lower damage per target trades against immediate hits and the ability to pierce several enemies in one column. |
|
||||
|
||||
Pulse Cannon is always equipped and fires alongside other primary guns. Seeker
|
||||
Swarm and Ion Lance occupy the selected special slot and fire with Fire or
|
||||
Special while selected. All three are reusable, consume no ammunition and have
|
||||
a maximum inventory count of one. Each equipment definition includes a shop
|
||||
description stating these controls and its target behavior.
|
||||
|
||||
## Controlled damage observations
|
||||
|
||||
The local benchmark loads the original asset catalog and original registered
|
||||
weapons, plus all six shipped weapon/enemy packages. Every weapon runs through
|
||||
the real `World::step` simulation and real scripts at difficulty 2. Each scene
|
||||
holds Fire for 700 steps, exactly 30 seconds at 70/3 Hz, against 32×32 fixtures
|
||||
with 1,000,000 health. The pilot remains at the initial position with no other
|
||||
weapons equipped. Ground fixtures use a test-only movement callback to cancel
|
||||
the normal one-pixel terrain scroll after each collision pass.
|
||||
|
||||
The numbers below include travel delay and misses during that 30-second window.
|
||||
They measure health lost per second, rather than nominal damage divided by
|
||||
cooldown.
|
||||
|
||||
| Weapon | Price | Aligned air damage/s | Aligned ground damage/s | Air target 76 pixels to the right damage/s |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| Original Forward Guns | 12,000 | 23.13 | 23.13 | 0 |
|
||||
| Original Plasma Guns | 78,800 | 4.67 | 0 | 0 |
|
||||
| Original Micro Missile | 175,600 | 23.07 | 23.07 | 0 |
|
||||
| Original Mini Gun | 250,650 | 12.57 | 12.57 | 16.27 |
|
||||
| Original Turret | 512,850 | 19.50 | 0 | 19.50 |
|
||||
| Original Pulse Cannon | 725,000 | 38.50 | 38.50 | 0 |
|
||||
| Original Death Ray | 950,000 | 80.00 | 80.00 | 0 |
|
||||
| Original Forward Laser | 1,750,000 | 266.67 | 266.67 | 0 |
|
||||
| Mod Pulse Cannon | 185,000 | 24.00 | 24.00 | 0 |
|
||||
| Seeker Swarm | 285,000 | 23.40 | 23.40 | 23.40 |
|
||||
| Ion Lance | 425,000 | 26.67 | 26.67 | 0 |
|
||||
|
||||
The original forward laser's native beam damage pass reaches ground enemies
|
||||
despite its historical air target metadata; the observations use its actual
|
||||
behavior. The original turret selects airborne enemies. Original weapons retain
|
||||
their native update and collision paths throughout this comparison.
|
||||
|
||||
Equipping Pulse Cannon with the starter Forward Guns produced 46.33 damage/s
|
||||
against either aligned target, compared with 46.20 for Forward Guns plus Micro
|
||||
Missile. Pulse therefore belongs beside that original primary upgrade, rather
|
||||
than below the 12,000-credit starter guns. Scripted angled shots also reached a
|
||||
second target in the cluster scene.
|
||||
|
||||
Seeker Swarm delivered 23.40 damage/s to an offset airborne or ground target.
|
||||
In a tight three-enemy cluster, it delivered 23.40 to the primary target plus
|
||||
7.80 to each of two neighbors: 39.00 combined. Its fragmentation is bounded;
|
||||
it does not damage every enemy on screen.
|
||||
|
||||
Ion Lance delivered 26.67 damage/s to each of two vertically separated targets
|
||||
in the same column: 53.33 combined. It delivered 80.00 combined across three
|
||||
overlapping column targets. It dealt zero damage to targets outside its launch
|
||||
column. It is a brief aimed beam, rather than a screen-wide attack.
|
||||
|
||||
## Economy and limits
|
||||
|
||||
Controlled first-mission runs starting with 100 energy and zero credits earned
|
||||
42,775 credits at difficulty 1 and 59,025 at difficulty 2 with starter guns.
|
||||
The in-game registration flow starts with 10,000 credits and 75 energy, matching
|
||||
the original hangar setup. Compared with the latter controlled gross
|
||||
reward, these prices represent approximately 3.13, 4.83 and 7.20 such payouts.
|
||||
Repairs and other purchases increase the saving time; later missions have
|
||||
different rewards. This comparison sets a progression tier and does not promise
|
||||
an exact purchase mission.
|
||||
|
||||
Stationary fixtures favor perfect alignment and long-lived targets. They do
|
||||
not establish equal campaign difficulty, measure moving-target accuracy,
|
||||
account for overkill against weak enemies or quantify projectile travel time
|
||||
against fast enemies. The benchmark also isolates weapons; real pilots can
|
||||
combine several primaries with one selected special. These prices are concrete
|
||||
initial balance choices, not an assertion that every loadout is equally strong.
|
||||
|
||||
Iron Coast Mission 1 intentionally supplies a free Pulse Cannon loan if the
|
||||
pilot does not already own one. The mission returns the loan at its end while
|
||||
preserving previously owned equipment. The trial therefore helps this mission
|
||||
without granting a permanent shop upgrade or a repeatable resale reward.
|
||||
|
||||
## Reproduce
|
||||
|
||||
Run the local-only test from the repository root with the original catalog:
|
||||
|
||||
```sh
|
||||
RAPTOR_BALANCE_REPORT="$PWD/.reference/weapon-balance.json" \
|
||||
cargo test --release --manifest-path RustRaptor/Cargo.toml \
|
||||
--no-default-features --test weapon_balance -- --ignored --nocapture
|
||||
```
|
||||
|
||||
`RAPTOR_TEST_DATA` can override the catalog directory. The optional JSON report
|
||||
records all 96 observations: fifteen weapons in six scenes, plus the three
|
||||
primary upgrades combined with Forward Guns against air and ground. Assertions
|
||||
check all-target homing, column piercing, off-axis beam misses, target survival
|
||||
and unchanged pilot shields. The test uses the Rust engine without SDL or C++.
|
||||
Original data and locally written reference reports stay outside Git.
|
||||
@@ -5,11 +5,11 @@ This API v1 example adds a scripted pulse cannon, a repair pickup, weaving drone
|
||||
From the repository root:
|
||||
|
||||
```sh
|
||||
cargo run --no-default-features -- --mods examples/mods --validate-mods aurora
|
||||
cargo run --no-default-features -- --mods examples/mods --enabled aurora \
|
||||
cargo run --no-default-features -- --mods mods --validate-mods aurora
|
||||
cargo run --no-default-features -- --mods mods --enabled aurora \
|
||||
--headless aurora:field_trials --ticks 700
|
||||
```
|
||||
|
||||
To play, start the Rust engine with `--mods examples/mods`, enable Aurora in **Mods**, apply the selection at the main menu, create a separate pilot and choose **Aurora Field Trials**. The mission equips its cannon on the first simulation step. Keep existing pilots' required mod sets available.
|
||||
To play, start the Rust engine with `--mods mods`, enable Aurora in **Mods**, apply the selection at the main menu, create a separate pilot and choose **Aurora Field Trials**. The mission equips its cannon on the first simulation step. Keep existing pilots' required mod sets available.
|
||||
|
||||
Content IDs intentionally separate the inventory item `aurora:pulse_cannon` from its projectile `aurora:pulse_projectile`. The scripts demonstrate `on_fire`, `on_hit`, `on_spawn`, `on_tick`, `on_death`, `on_pickup`, `on_use`, `on_mission_start` and `on_mission_end`. See `docs/modding-api.md` for the complete API and compatibility rules.
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,9 +1,9 @@
|
||||
# Ion Lance 1.0.0
|
||||
|
||||
Enable **Ion Lance** in Mods and apply at the main menu. This independent API 1 example has no dependencies. Buy its equipment in the shop (22,000 credits, maximum one) or collect its pickup. Choose it in Inventory or cycle special weapons during a mission. The equipped weapon fires with Fire or Special; it consumes no ammunition.
|
||||
Enable **Ion Lance** in Mods and apply at the main menu. This independent API 1 example has no dependencies. Buy its equipment in the shop (425,000 credits, maximum one) or collect its pickup. Choose it in Inventory or cycle special weapons during a mission. The equipped weapon fires with Fire or Special; it consumes no ammunition.
|
||||
|
||||
Projectile: 8 damage, 12 logical pixels per step, 14 step cooldown, `beam`, air and ground targets. The narrow beam pierces every enemy in its column for two steps (16 total damage per enemy per trigger). Rhai stores bounded burst/hit counters and emits local firing/impact sounds and effects.
|
||||
|
||||
`art/equipment-sd.png` is a 16×16 logical icon, `art/equipment-hd.png` its detailed 4× variant. Projectile canvases are 4×32 SD and 16×128 HD. Switch HD artwork in Options. The generated master images, SD/HD sprites, WAV files, provenance and reproduction inputs are tracked in Git. Original game assets and decoded reference images remain outside version control. `python3 generate_audio.py` reproduces both sound files.
|
||||
|
||||
Validate locally with `cargo run --no-default-features -- --mods examples/mods --validate-mods ion_lance`. Read the shared [API documentation](../../../docs/modding-api.md) for save pins, dependencies and sandbox limits.
|
||||
Validate locally with `cargo run --no-default-features -- --mods mods --validate-mods ion_lance`. Read the shared [API documentation](../../docs/modding-api.md) for save pins, dependencies and sandbox limits.
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"id": "ion_lance:equipment",
|
||||
"name": "Ion Lance",
|
||||
"price": 22000,
|
||||
"price": 425000,
|
||||
"max_count": 1,
|
||||
"initial_count": 1,
|
||||
"weapon": "ion_lance:projectile",
|
||||
@@ -41,7 +41,8 @@
|
||||
"logical_height": 16,
|
||||
"nearest": true
|
||||
},
|
||||
"script": "scripts/equipment.rhai"
|
||||
"script": "scripts/equipment.rhai",
|
||||
"description": "Selectable reusable special. A brief beam hits every air or ground enemy in the column ahead of your ship. Aim the column, then use Fire or Special while selected. No ammunition is consumed."
|
||||
}
|
||||
],
|
||||
"sounds": [
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-3
@@ -1,11 +1,10 @@
|
||||
// Built-in beam projectiles handle the normal volley and collision rules.
|
||||
// Callbacks add deterministic visuals, audio and serializable weapon counters.
|
||||
// Firing callbacks add audio and counters; impact callbacks add hit visuals.
|
||||
fn on_fire(event, state, random) {
|
||||
let bursts = if state.contains("bursts") { state.bursts % 100000 + 1 } else { 1 };
|
||||
let hits = if state.contains("hits") { state.hits } else { 0 };
|
||||
let commands = [
|
||||
#{ op: "play_sound", sound: "ion_lance:fire" },
|
||||
#{ op: "effect", x: event.x, y: event.y - 3 }
|
||||
#{ op: "play_sound", sound: "ion_lance:fire" }
|
||||
];
|
||||
#{ commands: commands, state: #{ bursts: bursts, hits: hits } }
|
||||
}
|
||||
@@ -14,4 +14,4 @@ Generated PNG masters, SD/HD strips, previews and WAV sounds are included in Git
|
||||
|
||||
To rebuild derived artwork from supplied generated masters and regenerate audio, install Pillow and run `python3 build_assets.py`. To regenerate only audio with the Python standard library, run `python3 build_assets.py --audio-only`. WAVs are original procedural mono 16-bit PCM at 22050 Hz; `audio-recipe.json` records deterministic seeds, sizes and hashes. The art pipeline resizes and assembles supplied images; it does not redraw them.
|
||||
|
||||
Validate from the repository root: `cargo run -- --mods examples/mods --validate-mods iron_coast_boss`. Synthetic behavior and save/replay tests: `cargo test --test enemies_mods`. Verify shipped artwork locally: `cargo test --test enemies_mods shipped_enemy_assets_are_valid_and_aligned`.
|
||||
Validate from the repository root: `cargo run -- --mods mods --validate-mods iron_coast_boss`. Synthetic behavior and save/replay tests: `cargo test --test enemies_mods`. Verify shipped artwork locally: `cargo test --test enemies_mods shipped_enemy_assets_are_valid_and_aligned`.
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -2,8 +2,8 @@
|
||||
"""Convert saved imagegen artwork and synthesize reproducible package-local WAVs.
|
||||
|
||||
This script resizes/atlases supplied art; it never redraws source or generated art.
|
||||
Generated source PNGs stay in ignored art/. See prompts/ and provenance.json.
|
||||
Use --audio-only to regenerate sound without Pillow or private artwork.
|
||||
Generated masters, SD/HD artwork and WAVs are tracked in Git. See prompts/ and provenance.json.
|
||||
Use --audio-only to regenerate sound without Pillow or processing artwork.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+8
-5
@@ -1,6 +1,6 @@
|
||||
# Iron Coast — Mission 1: Breakwater
|
||||
|
||||
Enable this package and its six dependencies in the in-game Mods screen:
|
||||
Enable this package in the in-game Mods screen to select its six installed dependencies automatically:
|
||||
`iron_coast_scout`, `iron_coast_turret`, `iron_coast_boss`, `pulse_cannon`,
|
||||
`seeker_swarm`, and `ion_lance`. Each package is independent and version 1.0.0.
|
||||
Choose **Iron Coast 1 — Breakwater** in the mission list.
|
||||
@@ -8,7 +8,10 @@ Choose **Iron Coast 1 — Breakwater** in the mission list.
|
||||
Disable at least two harbor turrets and destroy the command ship to complete
|
||||
the raid. Scout waves arrive during the approach; two supply depots release
|
||||
repair kits. When inventory space allows, the mission grants a trial Pulse
|
||||
Cannon and three field repairs. Granted equipment remains with the pilot.
|
||||
Cannon loan and three field repairs. The loan is returned before the completed
|
||||
flight is saved; a cannon you already own is preserved. Field repairs cost
|
||||
12,500 credits each in the shop, a premium over the original 10,000-credit
|
||||
hangar energy refill for use during combat.
|
||||
Repairs restore 25 shield when selected and used with the special button.
|
||||
Victory awards 5,000 credits in addition to ordinary destruction rewards.
|
||||
A full inventory can still start the mission; existing equipment is preserved
|
||||
@@ -25,10 +28,10 @@ report. Original game data and the original style-reference PNGs remain
|
||||
outside Git. The three
|
||||
`art/*-source-hd.png` inputs were generated with the built-in imagegen tool
|
||||
using the original terrain and military sprite as style/scale references.
|
||||
Run `python3 examples/mods/iron_coast_mission_1/build_assets.py --palette
|
||||
data/misc/PALETTE_DAT` to regenerate the exact
|
||||
Run `python3 mods/iron_coast_mission_1/build_assets.py --palette
|
||||
../data/misc/PALETTE_DAT` to regenerate the exact
|
||||
packaged crops, SD palette conversion, HD footprints and synthesized WAVs.
|
||||
See `prompts.md`, `asset-report.json`, and `docs/iron-coast.md` for provenance
|
||||
See `prompts.md`, `asset-report.json`, and [Iron Coast documentation](../../docs/iron-coast.md) for provenance
|
||||
and validation limits.
|
||||
|
||||
The release acceptance run completes with starter guns at step **882**
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 649 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user