Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Order of the Vile

A villain-protagonist Arthurian RPG for RPG Maker VX Ace, built from source.

You play Mordred. In Malory, Arthur is told a child born on May Day will destroy him, so he has every noble infant born that May Day set adrift to drown. Mordred is the one who washes up alive — and the prophecy only comes true because of what Arthur did to prevent it. The grievance is real, it stays real, and the game is about how far past it you go.


The build is the source

Nothing in this project is clicked into the RPG Maker editor. The database, the maps, the events, the Ruby scripts and every pixel of art are generated from src/ and tools/ into orderofthevile_game/.

python tools/build.py
python tools/verify.py

That matters for two reasons. .rvdata2 files are opaque binary blobs, so an editor-authored project is undiffable and unreviewable — here, a change to a skill is a one-line diff. And it makes the content scalable: adding twenty maps is adding twenty entries to a list, not twenty afternoons of tile painting.

Command Effect
python tools/build.py Data, scripts and art
python tools/build.py --no-art Data and scripts only (fast; art is ~8s)
python tools/verify.py Cross-reference and asset check
python tools/test_roundtrip.py Prove the Marshal codec is byte-exact
python tools/scripts_io.py extract Scripts.rvdata2 → editable .rb files

How it works

There is no Ruby on the build machine, so tools/rvdata2/rmarshal.py implements Ruby's Marshal 4.8 format directly — including the %.17g-plus-binary-mantissa float encoding that Ruby uses for bit-exact round-tripping. It is validated by reloading and rewriting every file the editor itself produced and requiring the output to be byte-identical. That test is the licence to author new ones.

tools/
  rvdata2/rmarshal.py   Ruby Marshal 4.8 codec
  rvdata2/rpg.py        RPG::* record constructors
  rvdata2/events.py     event-command DSL (handles all indent bookkeeping)
  art/                  procedural art pipeline
  build.py  verify.py   compile, then check
src/
  content/              database, world, maps and story
  scripts/custom/       the game's own RGSS3 scripts

Design

Vices replace Vows

In the knight version of this story each character swears a Vow — a restriction that grants power while it is kept. Here it inverts. Each member of the Order has a Vice: a compulsion that is already a source of power, and indulging it grants more.

Member Vice Indulging grants What it costs
Mordred Wrath Damage scales with your own missing HP Cannot flee, cannot accept surrender
Turquine Vengeance Huge bonus damage vs. Lancelot and anyone who has wounded him Will not follow orders that spare a target
Breunis Cruelty Killing the helpless fully restores his Dread Blocks every non-violent chapter resolution
Morgan Knowledge Learns any enemy skill she survives Each skill learned raises Corruption
Agravaine Envy Steals buffs from enemies and your own party At high Corruption, may act against you

Corruption is the real resource

One variable, on screen at all times, that only ever goes up. It buys stronger Vices, the Order's best skills, and dialogue that only opens when you are feared. It costs you control: members start acting on their own turns, merchants refuse you, informants run, and eventually one of your own knights comes for the Order — and which one depends on whose Vice you fed most.

This is the fix for the villain-protagonist problem. A villain game fails when it punishes you narratively for the villainy it made you do. Here cruelty always works, immediately and mechanically. The cost is never guilt — it is that you are building something unsustainable.

Dread replaces TP

It builds by killing quickly, executing the wounded, and ending a fight with nobody down. It drains when you show mercy or when something escapes. It carries between battles, because dread is a reputation.

There is no dedicated healer. Healing comes from consumables, from drain, and from Breunis restoring himself by killing the helpless. That single omission does more to make the party feel villainous than any amount of dialogue.

Common soldiers rout when Dread is high — they break, and you get exactly one turn to decide whether to spend actions running them down or let them carry the story of you somewhere else. It is a ten-second decision you make a hundred times, and it is the whole theme in miniature.

The hunts

Act II's chapters target one Round Table knight each, and you win by breaking their Vow. Gawain never refuses a challenge, so you engineer one he cannot survive and cannot decline. Percival never strikes the unarmed, so you put an unarmed innocent between him and the only thing that saves his brother.

Each has three resolutions: Corrupt (hardest — they join you), Kill (you get their relic weapon, and lose their content), Spare (lowest Corruption; they appear at the finale, against you — or in one ending, beside you).


Not looking like RPG Maker

The project ships with zero RTP assets. Every asset is generated by tools/art/. Specific decisions, each aimed at a known tell:

  • No autotiles. Only the non-autotile sheets (A5 and B) are used. VX Ace autotiles force the rounded, blobby RTP silhouette that players recognise instantly.
  • A custom windowskin. The stock blue glass bevel is on screen more than any other asset in the engine. (Its bottom-right quadrant is not decoration — the engine samples it as the game's entire 32-colour text and gauge palette.)
  • 48-pixel-tall sprites instead of the RTP's chibi proportions.
  • A serif face rather than the default gothic sans.
  • One light direction across tiles, props, portraits and battlers, so a torch sconce and the wall it hangs on agree about where the sun is.
  • A desaturated, cold palette, with warmth reserved for fire and blood, so that when warmth appears it means something.
  • One design per character driving sprite, portrait and battler — RPG Maker projects usually pair generator faces with unrelated sprites, and the mismatch gives them away.

Status

Complete and building: the toolchain, the art pipeline (79 assets), the Vice/Corruption/Dread systems, the UI replacement, the full database (65 skills, 35 weapons, 24 enemies, 26 troops, 24 states), and 19 maps covering the opening, the barrow hub, the six hunts and the assault on Camelot.

This is not yet Final Fantasy length. A 40-hour JRPG is a multi-year effort for a team, and what is here is roughly the first several hours plus the complete skeleton of the rest. What the build system buys is that the remaining length is content entry rather than engineering: a new region is an entry in MAP_ORDER, a new hunt is an entry in HUNTS, a new enemy is a row in ENEMY_SPECS. The systems, the art pipeline and the verification are all done and all scale.

On verifying the Ruby

There is no Ruby on the build machine, so verify.py does not attempt to check script syntax — an earlier line-based attempt reported the engine's own shipped scripts as broken, and a check that fails on known-good input is worse than none.

What it does check is alias targets, which is where the real breakage lives. Every alias new old in the project's scripts is resolved against the class hierarchy using only what earlier-loading scripts have defined, because Ruby binds the target at load time. This matters more than it sounds: the first build aliased Window_Message#create_sub_windows, which does not exist in VX Ace (the method is create_all_windows), and the game died with a NameError before the title screen. A naive whole-project scan passes that case happily, since our own file supplies the missing def further down.

Anything implemented in RGSS301.dll rather than in the scripts — the Font class, for instance — cannot be verified statically at all, so the optional setters there are probed with respond_to? before being assigned.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages