Facebook Twitter YouTube Frictional Games | Forum | Privacy Policy | Dev Blog | Dev Wiki | Support | Gametee


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Work in progress Using Lights to make any Image using only scripting
Apjjm Offline
Is easy to say

Posts: 496
Threads: 18
Joined: Apr 2011
Reputation: 52
#1
Using Lights to make any Image using only scripting

This isn't exactly going to be a tutorial just yet. Rather, a WIP tutorial Wink. I'm not really going to go into why i made this - as it is a rather long story with some spoilers in it, but here are some reasons you may want to use it:
  1. Displaying images / text that isn't simply an "image" in some resource folder
  2. Very weak obfuscation / protection of initial settings. Note that i say "very weak" as anybody can just open up your script file and add some "AddDebugMessages" or bypass the decoding!!! It might help if you want to hide a secret message in your level though.
  3. Creating a string which stores variables/settings for some purpose in non-plain text (E.g: Automatically creating an huge array by storing all the data in the string).
  4. Showing Representations of numbers in any base (Note: floats don't count here)
Short story of initial development
Spoiler below!

Anyway, I initially started work by creating a small console app which would take in two command line arguments - an input file and an output file - encoding the contents of the input file using an alphabet + token size to the output file. The output file was just a big string which I would copy into amnesia. Below is a rather redundant example using the tool to generate numbers in base 10:
0123456789
4
U1
U12
U123
U6789
The top line specified the input alphabet, the next line specifies the .no tokens (in this case digits) each number must take up. For example "1" would become "0001". This is necessary for the decoding stage.
The next 4 lines specify numbers, "U" just means "unsigned" and the numbers are the numbers you want to store. The output looks as follows:
0001001201236789
I then wrote a decoder - and added support for floats, signed ints and strings.




However, the final goal was to have an image stored in as little text as possible in my script file, and to then display it on the screen! All I needed to do here was to turn an image into a series of commands above, and supply an alphabet and token size. Luckily, this isn't too hard, and one quick program in c# later i have an image generator, and a few functions (and a few hours debugging Sad) later, I can generate the following using box lights ONLY and no gobos:
Spoiler below!

Problem?
[Image: yILHE.png]

From a level editor with only one box light (until scripting runs) for illuminating the player:
Spoiler below!

[Image: vf48d.png]


After I finish tweaking a few things, and finish documenting the newest functions I'll be posting the tools up and a tutorial on how to use the scripting commands. If you can't wait though, here's the amnesia scripting stuff minus the image loading shenanigans - note that this was designed with the updated notepad++ files which can be found here

Encoding functions HPS file: Mediafire D/L
(This post was last modified: 10-21-2011, 01:38 AM by Apjjm.)
10-21-2011, 01:26 AM
Find
Kman Offline
Posting Freak

Posts: 4,187
Threads: 25
Joined: Jul 2011
Reputation: 219
#2
RE: Using Lights to make any Image using only scripting

YOU ARE A GOD

Posting Freak
10-21-2011, 01:41 AM
Website Find
palistov Offline
Posting Freak

Posts: 1,208
Threads: 67
Joined: Mar 2011
Reputation: 57
#3
RE: Using Lights to make any Image using only scripting

I smell an incoming new project...Minecraft: The Dark Descent?

10-21-2011, 01:57 AM
Find
Acies Offline
Posting Freak

Posts: 1,643
Threads: 60
Joined: Feb 2011
Reputation: 73
#4
RE: Using Lights to make any Image using only scripting

Oh my god. Really cool.

[Image: mZiYnxe.png]


10-21-2011, 11:46 AM
Find
Apjjm Offline
Is easy to say

Posts: 496
Threads: 18
Joined: Apr 2011
Reputation: 52
#5
RE: Using Lights to make any Image using only scripting

Today I adjusted the system to fix a small bug and support colours. Still need to improve the int encoding routine, but pictures only require UINTs so that is low on the list of fixes right now. I also recorded a stress test with a picture using 10k lights, unsurprisingly this lagged a little bit - but it worked and looks really cool. I had to write a timer which drew half a column at a time so I could be sure the game didn't crash!





If you are interested in the string that was generated for this picture:
http://pastebin.com/D9yC3gbF
Using the alphabet:
string alphabet = " !()*+,-.0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz{|}";
uint tSize=4;

So, as it is, it really is only feasible for small images with less than 2k lights - but that was kind of obvious from the start.
(This post was last modified: 10-21-2011, 12:56 PM by Apjjm.)
10-21-2011, 12:50 PM
Find
Your Computer Offline
SCAN ME!

Posts: 3,456
Threads: 32
Joined: Jul 2011
Reputation: 235
#6
RE: Using Lights to make any Image using only scripting

LOL, that is epic! I saw the source code, but i was too lazy to study it, so i'll ask this here: Is the "image" size (lights boundary) based on a primitive plane, or is the dimensions of the original image being translated and adjusted in game? Also, are you able to specify the size of each pixel (light)?

Tutorials: From Noob to Pro
10-21-2011, 03:22 PM
Website Find
Apjjm Offline
Is easy to say

Posts: 496
Threads: 18
Joined: Apr 2011
Reputation: 52
#7
RE: Using Lights to make any Image using only scripting

To answer your question I guess I can just go for the full explanation as to how the approach is done currently:

(Released Part) The decoder & Encoder
This stage, as described in the first post just encodes values according to an alphabet. The "tSize" parameter represents the size of a "token" used per uint (or no. of characters of the alphabet used per uint). For example, if I were to use the hex alphabet
"0123456789ABCDEF" and a tSize of 4, i'd be able to represent the numbers from "0000" to "FFFF". Each UINT will always be stored with a total tSize characters from the input alphabet so that it is actually possible to decode. Ints, Strings and Floats are just stored as UINTS with extra information / a different interpretation.

At this stage we have the decoder and encoder functions as linked in the top post. Ontop of this i have two unreleased c# applications:
Image converter:
This tool lets you load in an image and set a down-sampling factor. This is just a glorified shrinking algorithm - it takes the image, averages out the color of a square (dimensioned specified by the down-size factor) and outputs that as 1 pixel in the new image. It repeats until the new image is a downsized copy of the old one. This is necessary on larger images (but completely optional) to keep the light count under 10k (after which it becomes unbearably slow). To output this image ready for encoding the program will then convert the RGB components of the smaller image into one 32bit UINT:
Bits 0-7: Red
Bits 8-15: Green
Bits 15-24: Blue
This is effectively a normal colour system without the alpha component.
And output a list of them as a file which the command-line encoder can take in. For the purposes of re-constructing the image, width and height are also exported as two UINTS at the top of the file. An Export Might look something like:
U42  <--- Width
U42  <--- Height
U1234 <--- Pixel (0,0)
U0      <--- Pixel (0,1)
U234   <--- Pixel (0,2) etc...
Which is run through...

Command-line encoder:
This tool takes a file of the form
<alphabet>
<tSize>
<Value 1>
<Value 2>
...
<Value n>
And outputs it as an encoded string. This is essentially the encoding routines as linked in the first post ported to c# so it can operate over a whole file and output the string into another. The image is now a string which can just be dumped into the source HPS file like "string x = <long thing representing image>;".

Decoding
Firstly, before any drawing occurs I decode the string into a 2D array of uints, since the first two values decoded by the string are width and height of the image, I use this to initialise the array. I then decode each set of "tSize" characters into the array.

Drawing:
At this stage I have a 2D array containing uints which contain the colours. To the draw the image I iterate through the array and use AddAttachedPropToProp to attach a custom variant of the "block_box" entity containing an additional box light called "light". This creates the light. I then decode the uint for this pixel into 3 floats for the color, and call FadeLightTo(boxname + "_light",...) to set it's color. The arguments for this function specify the width of the box light in the entity used to make box lights, amongst a host of other settings.

This works because I have a huge plane which intersects all the lights to give them something to illuminate in the editor. Each light is currently a standard 1x1x1 cube and drawn along XY (Y-Flipped) - but there is no reason why you couldn't change this.

There is no reason why you couldn't do something else with the pixel array - like compose several pictures together and then draw, or, have an array of pixel arrays for an animation. As i said, this i just an application of the encoding and decoding tools to make an image out of box lights. Unless you want it to output some kind of password (As part of a puzzle or as a save-state for episodic releases) or perform pixel based drawing and manipulation there isn't really much of a reason why you would use it for images.
10-21-2011, 04:57 PM
Find
Your Computer Offline
SCAN ME!

Posts: 3,456
Threads: 32
Joined: Jul 2011
Reputation: 235
#8
RE: Using Lights to make any Image using only scripting

That reminds me of the xbm (X BitMap) format.

Tutorials: From Noob to Pro
10-21-2011, 05:06 PM
Website Find




Users browsing this thread: 2 Guest(s)