I'm making a full VVVVVV recreation in Minecraft!

Started by Bentroen, March 29, 2019, 09:02:24 PM

Previous topic - Next topic


Hey, everyone!

I had VVVVVV lying around in my Steam library for a few years, after having briefly heard about it and buying it on a sale. Little I knew about how much I was missing by not having played it before -- until some time a month ago when I was bored and out of nowhere decided to see what it was about. And maaaan... what a game! (I guess we all know how good this game is, so I don't need to get into that ;D).

Being a bit of a gamer myself, Minecraft is also among my favorite games. Though I don't play the more "known" game modes a lot (i.e. survival, mini-games etc.), I'm part of the mapmaking community, which is to Minecraft what the custom level making community is for VVVVVV. MC mapmaking is all about creating entirely new experiences with the tools the game provides you, which sometimes can even make you forget you're still in Minecraft!

As a mapmaker myself, I like recreating games and experiences inside Minecraft as a way to show my love for them. That's why, after having played VVVVVV and liking it so much, I decided to do... *drumroll*

~ VVVVVV in Minecraft! ~

(In case you're wondering, here's some screenshots of the progress I made so far, including all rooms in the game imported to Minecraft as blocks!)

Though, there's a bit of a challenge. Being part of the VVVVVV community for just a bit over a month, there are tons of things about the game that I may not know and also haven't learned from the couple times I played it through.

On the other hand, I've seen many of you have done some substantial research on the technical side of the game since its release, as a way to make better custom levels (heck, some of you are on this board for seven years! xD)

And that's the reason behind this post. I'm looking for someone who could assist me with the technical side of the game, perhaps someone who has decompiled the game or just gathered a ton of information from being here for so long. Since a lot of the development is done through coding, I could even use some help with that too!

Though it's also possible to recreate stuff from observation, as I've been doing so far (e.g. by recording the game and counting how many pixels the player moves each frame to find their speed), knowing exactly what is happening under the hood can make it way easier to recreate things accurately. Topics like the internal command list or the stuff in this webpage are the exact kind of thing I'm looking for. :)

And even though there's a lot of info already available, most of it is directed towards custom level making. As such, some details are
simply omitted/not covered, likely because they're only used internally and not relevant to custom levels. I'm mostly looking for these missing bits and pieces, or rather, looking to know if they can be found in some way! :P
(e.g. what each of the flags in the save files is responsible for, how the flickering entity colors are calculated, how the enemy patterns on the Gravitron are decided etc. etc.)

I'd love to hear what you guys think about this project! Tell me if you are or know of someone who'd be interested in helping, and finally, thanks for reading! ;D


Info Teddy

Quote from: Bentroen on March 29, 2019, 09:02:24 PMhow the flickering entity colors are calculated
so, here's the run-down:

terry posted the source code to a function called Graphics::setcol() a while ago, but it's a bit incomplete. for one, he uses these functions RGBf() and fRandom(), which both seem a bit mysterious, along with this help.glow stuff. also, when i checked with a decompiler, the red and blue of color 36 were swapped.

so after decompiling the game, it turns out RGBf() just adds 128 to the RGB of each color, and then divides the red, green, and blue by three. fRandom() is just a random float between 0 and 1.

now to explain help.glow: the game runs at 1000/34 fps, which is 29.4117647058823529...repeating frames a second. the help is just the game's instance of a UtilityClass. on every frame, the game calls help.updateglow() to update help.glow, and it looks like this:
Code (C++) Select
void UtilityClass::updateglow() {
this.slowsine = this.slowsine + 1 < 64 ? nextsine : 0;

if (this.glowdir == 0) {
this.glow += 2;
if (this.glow > 61)
this.glowdir = 1;
} else {
this.glow -= 2;
if (this.glow < 2)
this.glowdir = 0;
so basically, help.glow will go from 0 to 62 and back, and this causes a glow.

i've made an (incomplete) list of which entities use which color:
Quote from: Info Teddy0 -
    - The player, alive
    - Cyan crewmate
    - Flip tokens (entity 5)
  1 -
    - The player, dying
    - Main game Intermission 1 crewmate dying

  3 -
    - Trinket
    - The Secret Lab warp token
  4 -
    - Unactivated checkpoint
    - Untouched terminal
    - Master of the Universe trophy base
  5 -
    - Activated checkpoint
    - Touched terminal
  6 -
    - Space Station color 2 enemies
    - Space Station color 6 enemies
    - Space Station color 11 enemies
    - Space Station color 22 enemies
    - Space Station color 27 enemies
    - Outside red enemies
    - Lab red enemies
    - Warp Zone red enemies
    - Ship red enemies
  7 -
    - Space Station color 4 enemies
    - Space Station color 8 enemies
    - Space Station color 21 enemies
    - Space Station color 24 enemies
    - Space Station color 28 enemies
    - Space Station color 30 enemies
    - Space Station color -1 enemies
    - Outside green enemies
    - Lab green enemies
    - Warp Zone green enemies
    - Warp Zone gray enemies (when not in finalmode)
    - Ship green enemies
  8 -
    - Space Station color 15 enemies
    - Space Station color 19 enemies
    - Outside pink enemies
    - Lab pink enemies
    - Ship pink enemies
    - Invalid main game enemy (entity 1 box)
  9 -
    - Space Station color 3 enemies
    - Space Station color 16 enemies
    - Space Station color 23 enemies
    - Space Station color 29 enemies
    - Outside yellow enemies
    - Lab yellow enemies
    - Warp Zone yellow enemies
    - Ship yellow enemies
10 - Warp token
11 -
    - Space Station color 7 enemies
    - Space Station color 9 enemies
    - Space Station color 12 enemies
    - Space Station color 17 enemies
    - Space Station color 25 enemies
    - Outside cyan enemies
    - Lab cyan enemies
    - Lab rainbow BG enemies
    - Warp Zone cyan enemies
    - Ship cyan enemies
12 -
    - Space Station color 0 enemies
    - Space Station color 5 enemies
    - Space Station color 13 enemies
    - Space Station color 26 enemies
    - Outside blue enemies
    - Lab blue enemies
    - Warp Zone purple enemies
    - Ship blue enemies
13 - Green crewmate
14 - Yellow crewmate
15 - Red crewmate
16 - Blue crewmate
17 -
    - Space Station color 20 enemies
    - Outside orange enemies

20 -
    - Pink crewmate
    - Space Station color 1 enemies
    - Space Station color 10 enemies
    - Space Station color 14 enemies
    - Space Station color 18 enemies
    - Space Station color 31 enemies
    - Outside purple enemies
    - Warp Zone pink enemies
21 - Gravitron squares

23 - The indicator arrow of offscreen gravitron squares

30 - Final Level Mastered trophy
31 - Space Station 1 Mastered trophy
32 - Space Station 2 Mastered trophy
33 - Laboratory Mastered trophy
34 - Warp Zone Mastered trophy
35 - The Tower Mastered trophy
36 -
    - Last 30 seconds on the Super Gravitron trophy
    - Win with less than 100 deaths trophy
37 -
    - Game Complete trophy
    - Flip Mode Complete trophy
38 -
    - Last 20 seconds on the Super Gravitron trophy
    - Win with less than 250 deaths trophy
39 -
    - Last 5 seconds on the Super Gravitron trophy
    - Last 10 seconds on the Super Gravitron trophy
    - Last 15 seconds on the Super Gravitron trophy
    - Win with less than 500 deaths trophy
40 -
    - Last 1 minute on the Super Gravitron trophy
    - Win with less than 50 deaths trophy

100 - Unactivated teleporter
101 - Teleporter that has had `activeteleporter` called on it
102 -
    - Teleporter that has had `activateteleporter` called on it
    - Master of the Universe trophy (if you have gotten it)

Things that DO NOT use the color function:
- Gravity lines that are not being touched right now
- Gravity lines that are being touched
- Roomtext
- Room names
- Coins
- Entity 6
- Entity 7
- The flash command (making the screen white)

now, Graphics::setcol() doesn't handle every color. most notably, roomtext, roomnames, and gravity lines do not use it.

for gravity lines, we need to talk about Graphics again. you see, the game's Graphics instance is named either one of two things: graphics or dwgfx, and the game can't make up its mind about what to call it. but they both point to the same thing. i'm just going to use the name graphics. now, the Graphics class has attributes linedelay and linestate. linestate goes from 0 to 9, and each number is just a unique color of the gravity line. linedelay is how many frames to wait before updating linestate, and linestate just goes from 0 to 1 to 2 to ... to 7 to 8 to 9 to 0 to 1 to 2 to ... to 7 to 8 to 9 to ..., every time it gets updated. whenever the game calls Graphics::drawentities() to draw every entity, graphics.linestate and graphics.linedelay both get updated at the start, like so:
Code (C++) Select
if (this.linedelay < 1) {
this.linedelay = 2;

this.linestate = this.linestate < 9 ? this.linestate + 1 : 0;
} else {
whenever the game draws gravity lines, with the function Graphics::drawgravityline(), it draws it with a certain RGB depending on what graphics.linestate is, and whether or not you've hit it.
if graphics.linestate is 0, it's (180, 180, 180)
if it's 1, it's (215, 215, 195)
2: (195, 215, 215)
3: (180, 180, 154)
4: (176, 225, 204)
5: (176, 205, 185)
6: (154, 154, 154)
7: (185, 215, 195)
8: (195, 225, 185)
9: (215, 215, 215)
if the gravity line is hit, then it's (96, 96, 96)

as for roomnames and roomtext, they're based directly on help.glow. so their color is: (196, 196, 255 - help.glow).


are you trying to make a MAP or a pixel art recreation?
if its a map i could try to help with command blocks

Ally 🌠

lol imagine using command blocks instead of functions