Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Calin Leafshade

#161
This is in AGS, yea. Adore is not ready for a real game yet.
#162
Site & Forum Reports / Re: Site Registration
Sat 31/05/2014 21:35:43
I remember doing to test many years ago. I remember it being pretty painless.
#163
The Rumpus Room / Re: Swaggy
Sat 31/05/2014 09:31:05
Look at my avatar.

Shit like that cannot be assigned a value.
#164

A cyberpunk adventure by Sanctuary Interactive


The Story

Kass_Seti, a leading member of hacktivist group Analogue Dawn, wakes on the streets of New Soho with a hell of a headache.
Her advanced cybernetic implants have malfunctioned, corrupting her memory, leaving her alone and offline on the streets of a London in crisis.

The Internet is heavily censored with every major service locked behind extortionate paywalls. This has allowed a second system, the illicit Free//Net, to flourish. Rival hacker group Watchl1st have become the dominant force on the system, moving from protecting its open values online to militant action in the real world.

Watchl1st's former allies Analogue Dawn strongly oppose this change and have declared war. Kass_Seti might be able to stop the violence, but first she has to repair the damage to her memory, not easy when she's in the wrong part of town with no way to call for help.

Screenshots




Features

  • An immersive, near-future adventure
  • Full voice over
  • Original soundtrack
  • Cinematic, widescreen resolution at a blistering 320x180.
  • Contextual interface
The Team

Written by Rebecca McCarthy (Azure)
Programmed and directed by Steven Poulton (me)
Background art by Hayley Griffiths (Sookiesock)
Character art by Matt Frith

Follow us on twitter @SanctuaryInter!
Visit the website!


Estimated for release on your personal computer system this summer.

#165
The scopes of AGS and unity are completely different. This simply isn't a viable idea if AGS is to stay a hobbyist tool.
#166
Sure thing.

heres my globalscript

Code: ags
int lastRoom = -1;

#ifdef USE_LUA

function game_start()
{

  int i = 1;
  while (i < Game.MouseCursorCount) 
  {
    Mouse.DisableMode(i);
    i++;
  }
  
  Mouse.Mode = eModeWalkto;
  
  Lua.SetVar("DebugMode", Lua.BoolValue(false));
  #ifdef DEBUG
  //Debug(4, 1);
  Lua.SetVar("DebugMode", Lua.BoolValue(true));
  #endif
  
  Lua.RunScript("main.lua");

  
  Lua.Call("FireEvent", Lua.StringValue("game_start"));
  
}



function on_key_press(eKeyCode keycode)
{  


#ifdef DEBUG
  if (keycode == eKeyCtrlX)
    Debug(3, 0);
#endif
  LuaValueList *l = Lua.NewValueList();
  l.Add(Lua.StringValue("on_key_press"));
  l.Add(Lua.IntValue(keycode));
  Lua.Call("FireEvent",l);
}

function on_mouse_click (MouseButton button)
{
  LuaValueList *l = Lua.NewValueList();
  l.Add(Lua.StringValue("on_mouse_click"));
  l.Add(Lua.IntValue(button));
  Lua.Call("FireEvent",l);
  
}

function on_event(EventType ev, int data)
{
  
  LuaValueList *l = Lua.NewValueList();
  if (ev == eEventAddInventory) l.Add(Lua.StringValue("AddInventory"));
  else if (ev == eEventEnterRoomBeforeFadein) l.Add(Lua.StringValue("EnterRoomBeforeFadein"));
  else if (ev == eEventLeaveRoom) l.Add(Lua.StringValue("LeaveRoom"));
  else if (ev == eEventGUIMouseDown) 
  {
      GUIControl *gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
      LuaValueList *lvl = Lua.NewValueList();
      if (Mouse.IsButtonDown(eMouseLeft))
      {
        on_mouse_click(eMouseLeft);
        lvl.Add(Lua.IntValue(eMouseLeft));
      }
      if (Mouse.IsButtonDown(eMouseRight))
      {
        on_mouse_click(eMouseRight);
        lvl.Add(Lua.IntValue(eMouseRight));
      }
      
      if (gc == null)
      {
        GUI *g = GUI.GetAtScreenXY(mouse.x, mouse.y);
        if (g != null)
          g.LuaMethod("OnClick",lvl);
      }
      else if(gc.AsButton != null) 
      {
        gc.AsButton.LuaMethod("OnClick",lvl);
      }
      return;
      
  }
  
  l.Add(Lua.IntValue(data));
  Lua.Call("FireEvent",l);
  
  
}

function repeatedly_execute_always()
{  
  Lua.Call("FireEvent", Lua.StringValue("repeatedly_execute_always"));
  Lua.Call("FireEvent", Lua.StringValue("late_repeatedly_execute_always"));
  Lua.SetVar("Blocked", Lua.BoolValue(true));
}

function repeatedly_execute()
{
  
    if (player.Room != lastRoom)
  {
      Lua.Call("FireEvent", Lua.StringValue("EnterRoomAfterFadein"));
      lastRoom = player.Room;
  }
  
    LuaValueList *l = Lua.NewValueList();
  l.Add(Lua.StringValue("LeaveEdge"));
  
  if (player.y > Room.BottomEdge)
  {
    l.Add(Lua.StringValue("bottom"));
    Lua.Call("FireEvent", l);
  }
  else if (player.y < Room.TopEdge)
  {
    l.Add(Lua.StringValue("top"));
    Lua.Call("FireEvent", l);
  }
  else if (player.x < Room.LeftEdge)
  {
    l.Add(Lua.StringValue("left"));
    Lua.Call("FireEvent", l);
  }
  else if (player.x > Room.RightEdge)
  {
    l.Add(Lua.StringValue("right"));
    Lua.Call("FireEvent", l);
  }
  
  Lua.Call("FireEvent", Lua.StringValue("repeatedly_execute"));
  Lua.SetVar("Blocked", Lua.BoolValue(false));
}



function unhandled_event (int what, int type) 
{
  LuaValueList *l = Lua.NewValueList();
  l.Add(Lua.StringValue("unhandled_event"));
  l.Add(Lua.IntValue(what));
  l.Add(Lua.IntValue(type));
  Lua.Call("FireEvent",l);
}


#endif
function dialog_request(int param) {
}

and the lua module called interop.lua

Code: lua
-----------------------------------------------------
--
--	Lua Control Module 
--
--  Calin Leafshade 
--
--	A module to register global events in lua
--
-----------------------------------------------------

local events =
{
	delegates = {},
	objects = {}
}

function events:registerObject(obj)
	table.insert(self.objects,obj)
end

function events:register(event, priority, callback)
  
	if type(priority) == "function" then
		callback = priority
		priority = 100
	end
  
	local callbacks = self.delegates[event] or {}
	self.delegates[event] = callbacks
	table.insert(callbacks, {f = callback, priority = priority})
  
	table.sort(callbacks, function(a,b)
		return a.priority < b.priority
	end)
  
end

function events:fire(event, ...)
	for i,v in ipairs(self.objects) do
		if type(v[event]) == "function" then
			if v[event](v,...) then break end
		end
	end
	for i,v in ipairs(self.delegates[event] or {}) do
		if v.f(...) then break end
	end
end

return events

then my main.lua looks something like this

Code: lua
Events = require('interop.lua')

function FireEvent(...) -- this is a global function to allow AGS easier access to it
	Events:fire(...)
end

--then you can use the events module like this in any lua file:

Events:register("game_start", function()
    aAudio:Play()
end)

--you can also make objects like this:

local myObject = {}

function myObject:repeatedly_execute_always()
    -- do this every frame
end

Events:registerObject(myObject)

-- This means that all the events in this object will be run when triggered by interop (if they exist in the object, they dont have to)

These events basically give you everything you need. You need to make your own hotspot interaction system but thats very easy and I can show you how if you need me to.

Any questions let me know!
#167
Two problems.

1) AGS script is too slow in tight loops required for per-pixel processing

2) AGS does its game logic *after* userland scripts have run. This means thats it's impossible to edit the current sprite because the game logic might change it at the end of the frame.

#168
By removing the unchanged pixels all I mean is only have your animation cover the things that change and having the rest blank (rgba 0,0,0,0).

There shouldnt really be any slowdown with 32bit sprites in the hardware accelerated mode. Characters, GUIS and Objects are drawn by the GPU so it should be plenty fast enough. Anything done with DrawingSurfaces would be slow because thats all done on the CPU.
#169
Because AGS does no inter-frame compression on the backgrounds I would advise against using them and using an object instead. By removing the unchanged pixels from the object animation you allow AGS's compression to work better and make your game smaller and make disk-memory transfers faster. This is especially important at large resolutions like 1080p and with non-pixel art.
#170
Hi Vince,

As far as I know all the documentation should still hold true. Nothing has changed since inception.

Generally speaking however, I don't return values from Lua to AGS. Because AGS has no way of dynamically casting objects it makes things very messy so I keep my entire game in the Lua domain.

For example of how I do this see the following link (cached from google because i stupidly deleted the database yesteday)  It includes a full description of interoperation between AGS and Lua with code examples.

http://webcache.googleusercontent.com/search?q=cache:s48HXgtCbOoJ:www.themccarthychronicles.co.uk/+&cd=1&hl=en&ct=clnk&gl=uk

With regards to the ports, the plugins are open source and currently included in the AGS git repo so there's no reason why the current ports couldn't use them (Lua can be compiled on a toaster). I'm not sure if the plugin is compiled by default though. You'd have to ask Crimson Wizard.

Edit: If you'd prefer something more complete, heres my entire AGS-Lua Interop system:

AGS: http://hastebin.com/sixikoruna.c (This is the *only* code in my AGS project)

Lua: http://hastebin.com/eqewuneceq.lua
#171
Editor Development / Re: AGS 3.3.1 - Alpha 1
Mon 05/05/2014 19:54:36
Quote from: monkey_05_06 on Mon 05/05/2014 17:24:47
Once I get a build that everyone's generally happy with then I'll dump it all into a single "initial" commit and pull that in instead.) ;)

Look up "rebasing"
#172
Thing 6.

Functions as actions.

Remember this:

Code: ags

function hHotspot1_UseInv()
{
    if (player.ActiveInventory == iFoo)
    {
        player.Say("I don't think i should use the foo with that.");
    }
    else if (player.ActiveInventory == iBar)
    {
        player.Say("Gee, I shouldnt use the Bar with that just now.");
    }
    else if (adInfinitum)
    {
        dieOfBoredom();
    }
    else
    {
        player.Say("that doesn't work");
    }
}


And this has to be repeated for *every* *single* hotspot.

How about this instead:

Code: lua


hHotspot1.UseInv = {
    [iFoo] = function() player:Say("I don't think I should use the foo with that") end,
    [iBar] = function() player:Say("Gee, I shouldn't really use the bar with that.") end
}

--now call it in your main game code:

local func = hHotspot1.UseInv[player.ActiveInventory] or unhandled -- unhandled is our generic "that doesnt work" function
func() -- call the function



Much neater, and the act of using an inventory item with a hotspot is more clearly defined without a bazillion if/else statements.
#173
Cool to see someone using stuff i made!

However, I did this a *long* time ago before I knew the "correct" way to do the collision detection and I kinda just guessed so I apologise if it's a little.. broken.

EDIT: This is the definitive guide on how to do it: http://www.gamedev.net/page/resources/_/technical/game-programming/the-guide-to-implementing-2d-platformers-r2936
#174
Thing 5.

Multiplicative tinting



AGS's tinting algorithm is weird and the lighting level is related to the saturation level which doesnt make a lot of sense. Lua is fast enough to tint character sprites on the fly, pixel by pixel, overwriting the default behaviour.

Re: tint mapping. You can do that easily enough without Lua. Just have a DrawingSurface open for your tintmap and grab the pixels every frame. It's the most simple of the things presented here and AGS Script is fast enough for it.
#175
4.

Use a sprite as a kind of "tint mask" to dictate the tinting/lighting of characters stood at that position which allows for gradual blending between tints.

Try starting with a blurred version of the background:



#176
Thing 1:

Dialogue *trees*.

AGS doesn't really have a true dialogue tree system in the traditional sense. Dialogues were a series of unconnected lists. So I made this:



True dialogue trees with link nodes and conditions. The code is loaded dynamically as lua scripts so any lua is valid within a dialogue script. Which brings me to...

Thing 2:

Dialogue scripting within main scripts.

There's no obvious reason why we should have to write cCharacter.Say("This is what I say"); all the time. It's a common enough thing to do and people dont write scripts like that. So what if we could do this:

Code: lua

if myValue > 1 then
    Billy: Gee, I sure hope myValue was bigger than 1
else
    Billy: Lol, myValue.. You cad.
end


Since we can preprocess lua code before running it this is pretty trivial to automatically convert to the correct code. Goodie time-saver!

Thing 3.

Rewriting the pathfinder.

AGS script is probably too slow to rewrite the pathfinder and the lack of a hashtable means looking up nodes would be perilously slow. In Lua we don't have this problem.



My new pathfinder is more accurate and has tunnel-based smoothing. Also, when walking, characters continue walking at the end of a node which avoids the nasty stopping that AGS characters have a tendency to do at sharp corners.

An added benefit of this is that the walking code is kept within the user domain which means you can dynamically edit the walking frames without that nasty 1 frame delay.

I think thats everything I've been playing with... THE POWER OF LUA! UNITE!
#177
The Rumpus Room / Make a noise.
Tue 22/04/2014 10:41:28
ooWEEEEEoooo
#178
EDIT: Nevermind, found the error.
#179
The concept of Layers is definitely something on my mind and it's something i'd like to add very soon.

I will reconsider the atlas thing if it's very unpopular.. I kinda thought it would be more convenient.
#180
I disagree.

When does it make sense to have multiple different images that are *not* part of a single animation?

Generally speaking each sprite is part of one animation and used nowhere else so doesn't it make more sense to contain the images in larger and less numerous files?
SMF spam blocked by CleanTalk