Jump to content
  • Advertisement

Greedy Goblin

Member
  • Content Count

    50
  • Joined

  • Last visited

  • Days Won

    3

Greedy Goblin last won the day on May 14

Greedy Goblin had the most liked content!

Community Reputation

43 Neutral

2 Followers

About Greedy Goblin

  • Rank
    Member

Personal Information

Recent Profile Visitors

2797 profile views
  1. Greedy Goblin

    Celebrating 20 Years of GameDev.net

    Congrats on an amazing milestone! I might have actually finished my game come your 40th anniversary. πŸ˜‚ 😭
  2. I don't get it... 3 pages of comments and I'm still clueless as to what the "game" is? All I've heard so far is, at best, a wishy-washy idea for what sounds more like a tech demo. Where is the gameplay, incentive to play, fun?
  3. Greedy Goblin

    New trailer feedback!

    The video is really good! It's really difficult to create compelling media, whether that be a promotional video or game or whatever. The game itself looks great and possibly like the kind of game that's gonna get me on the edge of my seat and shouting at the TV (in the same way Overcooked does)! πŸ˜„
  4. Greedy Goblin

    An Aspie Life Beginnings - JRPG/Adventure game about autism

    This looks amazing! Really well polished. What engine/language/tools do you use to make the game?
  5. Greedy Goblin

    Moving Forward.... And Up, Down, Left, and Right

    I like the art style!
  6. Greedy Goblin

    The Berg

    Album for The Berg
  7. Greedy Goblin

    The Berg

  8. Greedy Goblin

    Making a map (editor)

    When it comes to populating the game world with objects I didn't want to have to spent months building a map editor, I only need something fairly simple and creating a feature-rich editor with a whizzy GUI seemed like such a waste of time and effort. I've been down that road before and ended up building (and selling) a visual scripting framework but ultimately never finished the game I was working on at the time. So how did I decide to approach this without having to create a GUI for placing and transforming objects in the scene. Well, since this is a browser based game I have the Chrome debug console to hand... yep, with a few keyboard short-cuts and manual input in the debug console is how I decided to proceed; it's simple, unobtrusive and gets the job done without hassle. One requirement is that I have an editor "class/module" that I can drop right in to my project and remove with ease when I want to push the project to a live environment. To make it independent of the game as such (i.e. I don't have to include a reference to the editor in any of the game code), I keep the instantiation of the editor separate from the main game and force it to wait (asynchronously) for the game to load (that's when the editor can do the rest of it's own initialisation). e.g. async function theGameHasFullyLoaded() { await new Promise( resolve => setTimeout( async () => { if ( game.gameTime ) { resolve( true ); } else { await theGameHasFullyLoaded(); resolve( true ); } }, 2000 ) ); return true; } I use a few keyboard shortcuts to rotate (R key), translate (T key) and scale (Y key... I'm already using S for player movement and R, T, Y are next to each other on the keyboard). While using rotate or translate I can switch between X, Y and Z axes by using the corresponding keys. To place an object in the scene I hop over to the console and type... game.editor.selectModel("aircraft02").spawn() This spawns the selected model a little way in front of the camera. The newly spawned object then becomes the currently selected model which I can manipulate using my rotate, translate and scale keyboard shortcuts. Once I've done editing I can save my changes by going back to the console and typing... game.editor.save() This essentially just calls an action on my Node API which does the actual saving of data to a file. I feel like I need a picture to liven up this blog post... And that's about it for now. I need to add in basic collision meshes for these static objects yet. I'll probably just keep it simple and stick to cuboids and spheres for the sake of simplicity and performance. When it comes to loading these static scene objects when the game starts, this is handled by a MapContentService which only loads the objects that exist within the required quadrants (i.e. dependent on where the player is on the map) - I won't call it a quadtree 'cos... well, it's not (nothing as sophisticated as that!) and would probably be overkill for my needs.
  9. Greedy Goblin

    Mr Boom's Shipping Container

    Really nice work Rutin. I love the way the face texture looks from different angles. Loving all the Python-esque comments too. Reminded me I'd still got my old programmable calculator from my school days lying around... Reckon it still works too if I had the right batteries to hand.
  10. Greedy Goblin

    9 Tips on Making an Indie Game from a Solo Developer

    Really good to read about your (@slayemin) experiences as a solo dev (and realising I really am a solo dev as I have chosen to do programming, artwork, 3D modelling and music single-handedly). Keep on keeping on! I guess one additional piece of advice I'd give to other indie devs is not to give up the day job too early on. That's one mistake I made and it's taken me a few years to get back to where I was and start building my savings back up. That smells like a scam to me! I bet those guys do it all the time and make a fair bit of money from it.
  11. Greedy Goblin

    State changes (Reprise)

    Progress really has been slow of late and I'm just not finding the time I need to make serious progress. Not that it's a problem. This is a hobby project with no deadlines and is as much about the learning journey as it is about the end product. However, I have started making a simple map editor which I'll create a separate blog entry on later, but in the process of doing so I found that I wanted to make more use of my Stateful and When constructs and this led me to realise a few mistakes I'd made and how I could improve things. It also brought to my attention the Proxy object which had managed to fly under my radar. So I realised after putting things into practice that I had made a mistake with how I was storing the transitions against the Stateful object (I'd gone and created an array on the prototype which was then shared between instances of Stateful... it worked, but really not what I intended/wanted... duh!). So I played around with a few ideas and eventually it evolved into something I liked and felt was a substantial improvement on the original. The Stateful object now utilises Proxy and individual states no longer need to derive from the Stateful prototype, making it much easier to use (IMO). This is what it looks like now: const Stateful = { from( src ) { return new Proxy( Object.create( { _transitions: [], _state: src, set( newState ) { let matchingTransitions = this._transitions.filter( x => ( x.from === undefined || x.from === this._state ) && ( x.to === undefined || x.to === newState ) ); if ( matchingTransitions.length > 0 ) { let prvState = this._state; this._state = newState; return matchingTransitions.forEach( t => t.callback( prvState, newState ) ); } return false; }, get isStateful() { return true; }, is( comparitor ) { return this._state === comparitor; } } ), { get( target, prop ) { if ( [ "set", "_state", "_transitions", "isStateful", "is" ].includes( prop ) ) { return target[ prop ]; } return target[ "_state" ][ prop ]; } } ); } } module.exports = Stateful; The Proxy acts as a ... errr... proxy... between the Stateful object and the underlying state that it's created from. So when we want to create a Stateful variable we simply define our states as simple data containers and then create the Stateful variable from one of these. e.g. const EDITOR_CMD = { IDLE: { name: "IDLE" }, ROTATE: { name: "ROTATE" }, TRANSLATE: { name: "TRANSLATE" }, SCALE: { name: "SCALE" }, X_AXIS: { name: "X_AXIS", axis: AXES.X }, Y_AXIS: { name: "Y_AXIS", axis: AXES.Y }, Z_AXIS: { name: "Z_AXIS", axis: AXES.Z } }; ... this.currentAction = Stateful.from( EDITOR_CMD.IDLE ); ... Next comes the redefintion of When... function _then( statefulObj, src, dst, callback ) { if ( typeof ( callback ) !== "function" ) throw new Error( "callback must be of type function" ); src.forEach( s => { dst.forEach( d => { statefulObj._transitions.push( { from: s, to: d, callback: callback } ); } ); } ); } function When( statefulObj ) { if ( !statefulObj.isStateful ) { throw "Argument must be a Stateful object"; } return { changes: { from( ...src ) { return { to( ...dst ) { return { then( callback ) { _then( statefulObj, src, dst, callback ); } }; }, then( callback ) { _then( statefulObj, src, [ undefined ], callback ); } }; }, to( ...dst ) { return { then( callback ) { _then( statefulObj, [ undefined ], dst, callback ); } }; } } }; } module.exports = When; In my mind this seems more straightforward than the previous version and allows us to do cool things like this: When( this.currentAction ).changes .from( EDITOR_CMD.ROTATE, EDITOR_CMD.TRANSLATE, EDITOR_CMD.SCALE ) .to( EDITOR_CMD.X_AXIS, EDITOR_CMD.Y_AXIS, EDITOR_CMD.Z_AXIS ) .then( ( prevState, newState ) => { console.log( newState.name ); this.controls.axis = newState.axis; this.currentAction.set( prevState ); } ); Well, it's cool to me anyway (simple pleasures). 😁 That's it for now but I'll try and get a new blog up about my approach to building a simple map editor as soon as possible. Let me know what you think of the above and any improvements you might suggest (or any mistakes I've made!).
  12. Greedy Goblin

    Engine for browser text-adventure style games

    It's been a long time since I used Inform7 but I do remember it being quite easy to build a web site around it. http://inform7.com/write/publish/
  13. Greedy Goblin

    Engine for browser text-adventure style games

    Hey supermikhail! You might like to check out something called Inform7 which is specifically designed for interactive fiction (text adventures). http://inform7.com/ [update] in fact they even mention that it's been used to teach foreign languages so might be perfect for what you need... http://inform7.com/teach/teach/
  14. Greedy Goblin

    Revisiting Terrain Collisions

    It's been a while since my last blog entry as I haven't had much time to work on my game due to work, chores, Christmas and... err... Red Dead Redemption 2 πŸ˜‚. I have only managed to do little bits here and there over the past couple of months but decided to spend some time revisiting my codebase and refactoring much of it. I had a Terrain object which handled the rendering of the terrain, the ocean AND the terrain collision geometry. It was starting to feel crowded in there and I was just being lazy lumping it all into one class! So I've split out the collision geometry into a separate 'class' - TerrainCollisionBody. This also helps with what I wanted to do next... Up until now I have just been loading the collision geometry for the entire map into memory on initialisation (at this point in time it's 1,048,576 vertices but that may indeed grow considerably in the near future) which was eating up a lot of memory... at one point prior to a few optimisations it seemed to be using over 1GB of memory!! My intention was always to stream the collision geometry in from the Node.js server via a simple API; nothing amazingly clever but just loading chunks/quadrants in when the player moves towards the edge of the current quadrant and unloading any quadrants that we no longer need. So I finally completed this feature yesterday! Yippee! The memory usage has now hugely dropped down to a far more reasonable level of just over 100MB (dependent on how many quadrants are loaded) and of course it now loads far, far faster! The Approach On the server side I have a simple end point that returns the collision geometry as a simple JSON object. This consists of two arrays, one for vertices and one for faces. Each element in the faces array contains three indices which point to elements in the vertices array and a Vector3 which describes the pre-calculated face normal. The end-point takes parameters for the X and Z co-ordinates of a point on the map and a 'view size' - this determines the size of a square around the player for which it should load a subset of the collision geometry. On the client side I use the player position to determine which quadrants I need to load. This could be more than 1 quadrant since if the player is near a quadrant boundary I want to pre-load any applicable surrounding quadrants to create a seamless transition as the player steps into new quadrants. For example, in the diagram below, if the player is in the centre of a quadrant (the red X) then I'd only need to load the quadrant the player is in (unless it's already been loaded and then I do nothing of course)... If the player moves within a certain distance of the quadrant boundary then we could potentially need to pre-load up to 3 quadrants. e.g. The yellow areas represent the quadrants to load. I'm sure you get the idea by now so I won't go on. Once I've determined the quadrants I need to load all I have to do is determine the centres of each quadrant and request the collision geometry via the Node.js end-point. e.g. /api/terrain/collisiongeometry/get/-3072/7168/2048 ... where -3072 and 7168 are the X and Z co-ords of the centre of a quadrant (map centre is 0,0). The results are stored in an array of quadrants, each quadrant being an object containing all the vertices and faces for that quadrant. Any quadrants that are no longer required are deleted from the array to free up memory. I hope this makes sense to someone other than me. πŸ˜‚ Anyway, the result is pretty smooth so far! The only other thing to mention is that I only do the quadrant check once every 10 seconds since doing it every frame seemed unneccesary and the more milliseconds per frame I can free up for more frequent stuff the better. I think for my next task I'll start adding in a few static objects to the terrain (buildings etc) to make it more interesting. Then I think I may get what I have so far on a public facing server so other people can have a play around with it (hopefully).
  • Advertisement
Γ—

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net isΒ your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!