Adventure Game Studio | Forums

AGS Development => Editor Development => Topic started by: Crimson Wizard on 22 Oct 2018, 02:11

Title: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 22 Oct 2018, 02:11
UPDATE from 13th December 2018:
This is the practically working WIP version of a custom room viewport, built on top of AGS 3.5.0 (alpha 7):
Build: https://www.dropbox.com/s/lk7b25a8kwj9jfz/ags-3.5.0--roomviewport-wip5.zip?dl=0 (https://www.dropbox.com/s/lk7b25a8kwj9jfz/ags-3.5.0--roomviewport-wip5.zip?dl=0)
The feature is discussed here on github: https://github.com/adventuregamestudio/ags/issues/473 (https://github.com/adventuregamestudio/ags/issues/473)
Pull request: https://github.com/adventuregamestudio/ags/pull/535 (https://github.com/adventuregamestudio/ags/pull/535)
Source branch: https://github.com/ivan-mogilko/ags-refactoring/tree/ags3--roomviewport (https://github.com/ivan-mogilko/ags-refactoring/tree/ags3--roomviewport)

In short, this feature lets you to change the way ROOM (and all inside it) is shown on game screen. This is done by setting up Room Viewport and Camera.
Camera is an "eye" inside the room, that has certain size and position in room coordinates. The existing "viewport" commands in current AGS serve for the same purpose.
Viewport is a surface on game screen where what camera "sees" gets drawn to. It also has a size and position, but in screen coordinates.
You may imagine a piece of room (the size of camera) is cut out and pasted in the viewport, resized if necessary.

If the Camera is smaller than the viewport, then the room will appear scaled up on screen. If the Camera is larger than the viewport, the room will appear scaled down.

Note, that with the smaller Camera size you may get a scrolling room even with rooms that are equal to game's size.


Extra consequence is that from now on you may have room backgrounds (and essentially - rooms) of any size. For example, 320x120 room in a 320x200 game.
This may be useful if part of your game screen is constantly covered by GUI, or if you want to make one room which is smaller than others.


=======================================================================================


Script API:
Code: Adventure Game Studio
  1. builtin managed struct Camera
  2. {
  3.   /// Gets/sets the X position of this camera in the room.
  4.   import attribute int X;
  5.   /// Gets/sets the Y position of this camera in the room.
  6.   import attribute int Y;
  7.   /// Gets/sets the camera's capture width in room coordinates.
  8.   import attribute int Width;
  9.   /// Gets/sets the camera's capture height in room coordinates.
  10.   import attribute int Height;
  11.   /// Gets/sets this camera's room horizontal scaling relative to the viewport it is displayed in.
  12.   import attribute float ScaleX;
  13.   /// Gets/sets this camera's room vertical scaling relative to the viewport it is displayed in.
  14.   import attribute float ScaleY;
  15.  
  16.   /// Gets/sets whether this camera will follow the player character automatically.
  17.   import attribute bool AutoTracking;
  18. };
  19.  
  20. builtin managed struct Viewport
  21. {
  22.   /// Gets/sets the X position on the screen where this viewport is located.
  23.   import attribute int X;
  24.   /// Gets/sets the Y position on the screen where this viewport is located.
  25.   import attribute int Y;
  26.   /// Gets/sets the viewport's width in screen coordinates.
  27.   import attribute int Width;
  28.   /// Gets/sets the viewport's height in screen coordinates.
  29.   import attribute int Height;
  30.   /// Gets the room camera displayed in this viewport.
  31.   import readonly attribute Camera *Camera;
  32. };
  33.  

Viewport is a place on screen where room is drawn, defined in game coordinates (e.g. 0,0 - 320x200).
Camera is a place in room which is being drawn. Camera size may be determined in two ways:
a) explicitly setting Width and Height, which tells actual rectangle in the room;
b) setting ScaleX and ScaleY properties to automatically adjust displayed room relative to the viewport's size.
For example, if you set ScaleX/Y to 2.0, then room will appear zoomed in twice as large as the viewport's size. If you set ScaleX/Y to 0.5, it will appear twice as small (zoomed out).
NOTE: you cannot set camera size larger than the room's background, and it generally does not support "seeing" beyond room's background, same as before.

You access viewport and camera using commands:
Code: Adventure Game Studio
  1. Viewport *Game.RoomViewport;
  2. Camera *Room.Camera;
  3.  


Also:
Code: Adventure Game Studio
  1. /// Gets/sets whether the viewport should automatically adjust itself and camera to the new room's background size
  2. Game.AutoSizeViewportOnLoad;
  3.  

Old viewport functions are now deprecated, they may still be enabled if you set "Script compatibility level" to v3.4.1 or lower.
Here's correspondence between old and new functions:

* SetViewport(x, y); ===> Room.Camera.X = x; Room.Camera.Y = y; Room.Camera.Auto = false;
* ReleaseViewport(); ===> Room.Camera.Auto = true;
* GetViewportX(); ===> Room.Camera.X;
* GetViewportY(); ===> Room.Camera.Y;


Little demonstration:
https://www.dropbox.com/s/l9783w8t1i8qk3t/roomcameramadness.mp4?dl=0 (https://www.dropbox.com/s/l9783w8t1i8qk3t/roomcameramadness.mp4?dl=0)

At this point nothing of above is set in stone, and I'd very much appreciate any functionality tests and thoughts on script commands.


KNOWN ISSUES:
 * because of a bug the AGS script does not let you write "Room.Camera.X = 10"; instead you have to do something like:
Code: Adventure Game Studio
  1. Camera *cam = Room.Camera;
  2. cam.X = 10;
  3.  
   this is very inconvenient indeed, and I think we need to fixing this issue, or change something in the above script API to make it simplier.
 * some possible optimization issues with software renderer when you change camera size too often.



=======================================================================================




The purpose of these features are:
1) Display room in a custom rectangle on screen;
2) Add zoom in/out effects in your game.
3) Potentially - also add rotation to the room view (if I am able to make it work correctly).

This also have a potential to have multiple room cameras in the future, although that may not be easy to add so I don't really plan to do that for AGS 3.5.0. The problem here is not so much in drawing them on screen, but rather in resolving interactions. Right now all the logic in AGS is based on the single viewport into the room: clicks, finding objects on screen, etc. Multiple viewports would demand a good thought and possibly script redesign.
Spoiler: ShowHide
 But like I said, drawing them alone is not a problem:

Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Danvzare on 22 Oct 2018, 11:35
Ooh, sounds useful.
With something like that, it should be possible to make some really cinematic looking games.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: eri0o on 22 Oct 2018, 23:29
Multiple cameras could be used for minimaps. Other than this I don't see much use for multiple cameras.

I am adding below an error that occurs when I leave this AGS and an error that occurs when I open this AGS after closing it.
Spoiler: ShowHide

(https://futureflashbackgame.com/AGS_FORUM_RESOURCES/helping_topics/ags_error.png)
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 22 Oct 2018, 23:50
Multiple cameras could be used for minimaps. Other than this I don't see much use for multiple cameras.

Basically any case of looking into something while still seeing your current position: zooming into an item/object or peeing into a keyhole, simulating an event in "another room" without actually changing rooms - all this could be simulated by displaying a separate and otherwise unaccessible part of the room in a second viewport. Showing two or more locations at once during cutscene. Split-screen multiplayer. These are cases I may think of.

It may be non optimal for a minimap though, since engine will have to process every sprite it sees, including its tints, lighting, scaling, walkbehinds etc.


I am adding below an error that occurs when I leave this AGS and an error that occurs when I open this AGS after closing it.

This might be a previously reported error that happens when you close the 3.5.0 Editor. But this time there is some interesting information about SpriteCache destructor.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Danvzare on 23 Oct 2018, 11:58
Multiple cameras could be used for minimaps. Other than this I don't see much use for multiple cameras.
I can. Finally we can make a splitscreen adventure game! :-D

And yes, I have always wanted to do that.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 18 Nov 2018, 23:08
Updated the test build, now supports Software renderer too (this means 8-bit games):
https://www.dropbox.com/s/au7nw0zjrr13eaq/ags-3.5.0--roomviewport-wip2.zip?dl=0

Built on top of the latest 3.5.0 Alpha 7, so to test this you may install a copy of 3.5.0 somewhere and unpack the archive over it.

Still TODO:
- Better script API to manage the new viewport/camera functionality;
- Some optimisation for software rendering.
- more testing...
- Actually allowing room backgrounds of any size (less than game screen).
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 30 Nov 2018, 00:04
New update: https://www.dropbox.com/s/e8i10xh8x28dn6q/ags-3.5.0--roomviewport-wip3.zip?dl=0

This mostly fixes some issues with software renderer.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 02 Dec 2018, 17:20
Alright, here's practically working version with a new script API:
https://www.dropbox.com/s/ecc5ldzi1dqvc5k/ags-3.5.0--roomviewport-wip4.zip?dl=0

Script API:
Code: Adventure Game Studio
  1. builtin managed struct Camera
  2. {
  3.   /// Gets/sets the X position of this camera in the room.
  4.   import attribute int X;
  5.   /// Gets/sets the Y position of this camera in the room.
  6.   import attribute int Y;
  7.   /// Gets/sets the camera's capture width in room coordinates.
  8.   import attribute int Width;
  9.   /// Gets/sets the camera's capture height in room coordinates.
  10.   import attribute int Height;
  11.   /// Gets/sets this camera's room horizontal scaling relative to the viewport it is displayed in.
  12.   import attribute float ScaleX;
  13.   /// Gets/sets this camera's room vertical scaling relative to the viewport it is displayed in.
  14.   import attribute float ScaleY;
  15.  
  16.   /// Gets/sets whether this camera will follow the player character automatically.
  17.   import attribute bool Auto;
  18. };
  19.  
  20. builtin managed struct Viewport
  21. {
  22.   /// Gets/sets the X position on the screen where this viewport is located.
  23.   import attribute int X;
  24.   /// Gets/sets the Y position on the screen where this viewport is located.
  25.   import attribute int Y;
  26.   /// Gets/sets the viewport's width in screen coordinates.
  27.   import attribute int Width;
  28.   /// Gets/sets the viewport's height in screen coordinates.
  29.   import attribute int Height;
  30.   /// Gets the room camera displayed in this viewport.
  31.   import readonly attribute Camera *Camera;
  32. };
  33.  

Viewport is a place on screen where room is drawn, defined in game coordinates (e.g. 0,0 - 320x200).
Camera is a place in room which is being drawn. Camera size may be determined in two ways:
a) explicitly setting Width and Height, which tells actual rectangle in the room;
b) setting ScaleX and ScaleY properties to automatically adjust displayed room relative to the viewport's size.
For example, if you set ScaleX/Y to 2.0, then room will appear zoomed in twice as large as the viewport's size. If you set ScaleX/Y to 0.5, it will appear twice as small (zoomed out).
NOTE: you cannot set camera size larger than the room's background, and it generally does not support "seeing" beyond room's background, same as before.

You access viewport and camera using commands:
Code: Adventure Game Studio
  1. Viewport *Game.RoomViewport;
  2. Camera *Room.Camera;
  3.  


Old viewport functions are now deprecated, they may still be enabled if you set "Script compatibility level" to v3.4.1 or lower.
Here's correspondence between old and new functions:

* SetViewport(x, y); ===> Room.Camera.X = x; Room.Camera.Y = y; Room.Camera.Auto = false;
* ReleaseViewport(); ===> Room.Camera.Auto = true;
* GetViewportX(); ===> Room.Camera.X;
* GetViewportY(); ===> Room.Camera.Y;



KNOWN ISSUES:
 * because of a bug the AGS script does not let you write "Room.Camera.X = 10"; instead you have to do something like:
Code: Adventure Game Studio
  1. Camera *cam = Room.Camera;
  2. cam.X = 10;
  3.  
   this is very inconvenient indeed, and I think we need to fixing this issue, or change something in the above script API to make it simplier.
 * some possible optimization issues with software renderer when you change camera size too often.



Little demonstration:
https://www.dropbox.com/s/l9783w8t1i8qk3t/roomcameramadness.mp4?dl=0

At this point nothing of above is set in stone, and I'd very much appreciate any functionality tests and thoughts on script commands.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 13 Dec 2018, 15:33
Another update. I have fixed number of bugs since previous versions. (The fact that no one reported them probably means that no one have tried it...  :( )
https://www.dropbox.com/s/lk7b25a8kwj9jfz/ags-3.5.0--roomviewport-wip5.zip?dl=0 (https://www.dropbox.com/s/lk7b25a8kwj9jfz/ags-3.5.0--roomviewport-wip5.zip?dl=0)

Also added Game.AutoSizeViewportOnRoomLoad which lets you control whether viewport is reset to default size when the new room is loaded.

I don't remember if this was in previous version already, but from now on you may have rooms of literally any size, for example have a 100x100 room in a 320x200 game, and so forth. This allows you to stop adding those empty black borders to the room backgrounds if part of your game screen is supposed to be covered by fixed GUI.


I haven't found any serious bugs in this latest build, so unless someone else does I am going to embrace and put this into the 3.5.0 release.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: eri0o on 25 Dec 2018, 16:06
using version from here -> 3.5.0.8 here (http://www.adventuregamestudio.co.uk/forums/index.php?topic=55829.msg636599086#msg636599086)

Yo, I am using Camera *cam = Room.Camera ! I want to do a GetWalkableAreaAt! When I use a camera that doesn't use System.ViewportHeight and System.ViewportWidth, as cam.Height and cam.Width, I can't seem to figure out how to get it correctly!  ???

Also , think it broke this (it's ignoring cam.Height and cam.Width) ->
Code: Adventure Game Studio
  1.   if (keycode == eKeyCtrlA) Debug(2,0); // Ctrl-A, show walkable areas
  2.  

Nevermind -> Figured out -->>

Code: Adventure Game Studio
  1. function GetWalkableAreaAtRoomXY(int x, int y){
  2.   Camera * cam;
  3.   cam = Room.Camera;
  4.   Viewport * vport = Game.RoomViewport;  
  5.   int walkableat;
  6.  
  7.   walkableat = GetWalkableAreaAt(vport.Width*(x-cam.X)/cam.Width+vport.X,
  8.                       vport.Height*(y-cam.Y)/cam.Height+vport.Y);
  9.    
  10.   return walkableat;
  11. }
  12.  


Did something (https://streamable.com/p9woa)

Download AGS PROJECT HERE (https://drive.google.com/open?id=1Xdo9Y8TD0EGOga2sf5yJBfEUQZTHcoR3)


Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 25 Dec 2018, 17:01
@eri0o I guess you did the math right, but I wanted to save people from doing that by hand, so my next ammendment to the cameras are these functions:
https://github.com/adventuregamestudio/ags/pull/549

In short there will be commands like Viewport.GetRoomLocation and Viewport.GetScreenLocation that convert screen coordinates to room and back through the given viewport, as well as Screen.GetRoomLocation which first finds if there is any viewport at a given point and if there is then does Viewport.GetRoomLocation. The latter is assuming that there may be multiple viewports (at some point in future).


Also , think it broke this (it's ignoring cam.Height and cam.Width) ->
Code: Adventure Game Studio
  1.   if (keycode == eKeyCtrlA) Debug(2,0); // Ctrl-A, show walkable areas
  2.  

It's quite possible that I missed some command. Since this code is already in repository could you open a bug report?
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: eri0o on 25 Dec 2018, 19:16
here is the new issue on github (https://github.com/adventuregamestudio/ags/issues/550)! Just freshly opened. :) I will try to add more details later.

Also thanks for the new handy functions, they will be handy :D

One thing about the walkable/region/hotspot areas, imagining a multiple camera/viewport situation, the functions would require both camera and viewport information to be able to get the correct X and Y, wouldn't?
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 25 Dec 2018, 19:58
One thing about the walkable/region/hotspot areas, imagining a multiple camera/viewport situation, the functions would require both camera and viewport information to be able to get the correct X and Y, wouldn't?

Viewport has a reference to Camera it is rendering. Right now its a readonly property, later it may become settable to change cameras in a viewport.
When converting coordinates from screen to room and back viewport is using its camera reference already.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: eri0o on 26 Dec 2018, 01:33
Hey CW, I think I have two additional questions on this feature:

why Game.RoomViewport, instead of Room.Viewport ? Is Game.RoomViewport the same for all Rooms and if it would be in Room.Viewport it would get destroyed on each Room load?

Also Camera.ScaleX and Camera.ScaleY, I think they should not existe, since the Viewport has a Camera assigned to it, but the Camera "doesn't know" about the viewport - so if there would exist a ScaleX and ScaleY, they should belong to the Viewport and not the Camera, right? Example, a Camera could theoretically be assigned to two Viewports.

Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: Crimson Wizard on 26 Dec 2018, 02:11
why Game.RoomViewport, instead of Room.Viewport ? Is Game.RoomViewport the same for all Rooms and if it would be in Room.Viewport it would get destroyed on each Room load?

Viewport does not belong to the room but to the screen. Room class has things that exist in the room and room's coordinate system. Viewport is a rectangle on the screen, which draws contents of room camera.
If we theoretise about multiple rooms loaded at the same time viewport will still be same and not owned by any room in particular.
BTW I like to move this property from Game to Screen class as next update, since Game is a hoard of various functions and properties already.


Also Camera.ScaleX and Camera.ScaleY, I think they should not existe, since the Viewport has a Camera assigned to it, but the Camera "doesn't know" about the viewport - so if there would exist a ScaleX and ScaleY, they should belong to the Viewport and not the Camera, right? Example, a Camera could theoretically be assigned to two Viewports.

This is something that is bothering me because there is more problems in this than just question of who knows who.

Initially I wanted this simply as means of automating camera size. I had a long thought before putting it to camera. I think in the end I did this because it is Camera that currently sets the boundaries of the visible part of the room with Camera.Width and Camera.Height. If I'd move Scale to Viewport then there would be inconsistency between camera's Width/Height and viewport's demands to scale camera to what it wants. Then viewport would have to actually modify camera's width and height, which could make sense but in turn bring question about multiple viewports using same camera (and generally would mean that viewports control cameras while now they only connected to them).
Currently it's like the camera has two modes: fixed size that's always the same and stretched to viewport and dynamic size that adjusts itself to viewport to match the required scaling. Since its camera that has both properties it may switch between them.

But thinking this over again, the biggest issue right now is not even that scaling is set by camera but that with non-fixed size you cannot tell how to position camera around player unless you put both camera and viewport into calculation, because right now the camera's position is defined as a top-left of a rectangle, and for example when tracking the player character camera is placed at character's location minus half-size of camera.
So this is truly not good at all.

What are the alternatives?

1) Completely moving camera's field of view configuration to the viewport. This will leave only position in camera (and probably rotation when its supported).
In such case we also must change how camera's position is determined and speak of a point in room camera is centered at instead of a rectangle in room. This is not necessarily bad, but will change the positioning logic agsers were used to.

2) Or completely remove automatic scaling property and leave camera with fixed Width and Height which is probably logical variant too, but users will have to calculate camera size themselves if they want to achieve certain level of zoom.

PS. I am actually leaning towards removing scaling property at all... at least for now. There is no automatic re-centering anyway and it is not hard to calculate Width and Height for the required zoom by multiplying or dividing viewport by some float.
Title: Re: [Experiment] Custom Room Viewport and Camera
Post by: eri0o on 26 Dec 2018, 10:06
I see no problem in removing Scale, I think the API should be as small as needed. Zoom could be provided by a module, and it would mostly likely have TweenZoom too. The advantage of the module is that it's API can evolve faster.

I understand the camera as a way to transform pixels from the game world to the pixel space of the Viewport. So for Zoom the Camera Width and Height would be make smaller, but mapped to a viewport that stays at the same size.