Light Guardian

Light Guardian

  • Tero Hannula
  • 1 year ago
  • 51st

Idea was to make sequal for my previous jam game:
though I got more interested playing around with shaders, so didn't manage to do any gameplay. So this is more of tech demo, trying out normal mapping. Game camera is 3D with orthographic projection, and then sprites are billboarded towards camera.

This video shows pretty much there is to it:

Some things

  • You can Hold TAB to see Normal map and without lighting effect.
  • Hold TAB and press "1" to change between different resolutions.
  • You can run with Shift
  • You can Fullscreen with F4, but be warned, I think GMS2.3 has bug which atleast crashes my computer when going from Fullscreen-to-Window.

Here is about how I approached drawing stuff, this isn't tutorial, but how I went and did things. And this is bit simplified and what I can rememeber from memory.

In short: Every object draws itself on surface, and in other surface their normal maps. These are combined in shader. More complicated:

  • Game uses normal maps to give depth to flat sprites. Here is short thing about normal maps:

  • Codewise Every object has own two draw-methods created in Creation-event. Draw-event is empty (only // comment).

  • For example:

    • For basic: "Draw = function() {draw_self(); } ", this method can have more drawing stuff too.
    • For Normal: "DrawNormal = function() {draw_sprite_ext(...); } ", and choose Normal-map sprite.
  • Have two global priority lists: first for basic drawing, and other Normal-map.

  • In step-events every drawable object adds themselves on these two priority lists -> Calls global function DrawSelfNormal();

  • Inside this function is something like this:

    • "function DrawSelfNormal() { var _priority = point_distance_3d(x,y,z,obj_cam.x,obj_cam.y,obj_cam.z); ds_priority_add(global.list_draw_basic, id, _priority); ds_priority_add(global.list_draw_normal, id, _priority); } "
  • Function adds just instance's id for drawing. It calculates priority, which is the depth-sorting.

  • Now in draw-control object in loop through these lists to draw them in depth-sorted order.

  • Draw-control has two surfaces for basic and normal-maps, but I didn't draw directly to them.

  • draw_clear(c_black) to empty application_surface, then draw all normal-map events.

    • In loop we find instance id like "var inst = ds_priority_find_max(...)" and then draw by "inst.DrawNormal();".
  • Now I copy application_surface to normal-map surface. We are done and our surface is normal-map

  • Clear application surface, and then draw basic things like same. I copied this to another surface.

  • I also added player high-light to third surface. Highligths would have been used for another thing too.

  • In GUI -event draw application surface with normal-map shader. I made shader also cut values, so light edge is more clear.

  • Colors are added by drawing over colored rectangle with gpu_set_blendmode();

  • About shader I'll write later.

In short, I didn't use ray-casting, because my initial try with it was too jittery. So I made hacky way:

  • Every object which casts shadow draws primitive. Primitive consists two triangles.
  • Every object has starting width for shadow, and has two vertices next to it, always angled towards light.
  • Two other vertices are calculated from direction from light to these vertices.
  • Distance is given large enough number so shadow end doesn't appear in screen.

    During jam I just googled stuff etc. and one article I would to bring up is this:

You must be logged in to leave feedback
Log in Register an account
  • baku

    Unfinished as it is, it is at the very least incredibly pretty. Cool technology!



  • Kwis
    • Level 63

    1yr ago

    The visual style is interesting, but oh boy how quickly you lost yourself! If you ever make a game using this, make sure to add objects that can help the player figure out where to go (by making objects identifiable to differentiate different parts of the woods)

    Also the statue thing really creeped me out, nice!

    • Tero Hannula

      Thanks for trying out :) Yeah I'm aware that address is currently confusing. As I knew I wouldn't get any gameplay done, I didn't bother adding more elements there. So I just made huge forest to wander around. More compact areas, roads, cable thingies, signs, roadposts etc. Would help with sense of direction.

      The statue was made from debug object, three stacked smilies 😅 Hopefully you got the feeling and idea I would have wanted from the game :)

  • dosto
    • Level 15

    1yr ago

    The visual style (graphics, lights and perspective) creates a really immersive experience considering the fact that there isn't really anything to play. Waiting to see you exploit this technique in your future games!

    • Tero Hannula

      Thanks :) the lighting and art style would have been important tools for narrative purposes. As I didn't get original idea done, I almost repurpose this for zombie slaughter game (hordes keep growing), though I didn't have energy or inspiration to do so during jam.

  • Kyon
    • Level 22

    1yr ago

    Artstyle is super inspiring, nice job Tero <3

  • Ash
    • Level 1

    1yr ago

    Really really gorgeous, wish it was more!

  • Tydecon Games

    I think the visuals and the idea is very promising but you might have been a little overly ambitious given the time you had, it's a good foundation and I hope you turn it in to something incredible :)

    • Tero Hannula

      Thanks :) Early one I decided to just try learning shader etc., as I had no real idea for actual game. So I didn't stress too much, watched movie and slept well. I thought if I have time left after visual, then do something. Well atleast I got intro thingy.

  • Allison James

    It's a shame there's no gameplay here - the underlying tech, and the resulting graphics, are phenomenal, and you need to take the engine and do something with it 😄

    • Tero Hannula

      Thanks :) Yeah, I got the feeling I wanted from initial thought, but that cost me everything else ^^" Lot of spaghetti code, and need to rewrite things first.

      Text-system was made three times x) Intro, instructions and interaction have all own code. Interaction-code could have been used for all of them, but I made it last :V

  • Brian LaClair

    Looks absolutely beautiful - great work on the technical end of things. Wish it was something more than that! Keep working on this one.

  • SwiggityCricket

    Fantastic visuals. Like you said in your description, it's unfortunate you couldn't add any real gameplay. The ray tracing was cool.

    • Tero Hannula

      Thank for playing :) There is no actual raytracing, I did tried to do that first, but it was too jittery or too expensive with more rays, so I faked it. Every game object draws primitive from four vertices/points, which are calculated based on distance from light and direction to it. It was hacky solution, but hey, most importantly it worked :)

  • Chris

    Wow, this game has some of the coolest visual effects I've seen in a game maker game. Really awesome style and the character sprites are great too

    • Tero Hannula

      Thanks :) I drew mockup picture, which feeling I tried to capture, and I think I managed to do it pretty well. Though then I didn't get to do any gameplay. I drew character in 6 directions, so so rotating camera would feel better than just 4 directional, and 8 dir. felt too cumbersome.