Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 24 Mar 2001
Offline Last Active Today, 10:21 AM

#5308884 the dreaded "escort" quest

Posted by on 31 August 2016 - 12:50 PM


Think about NPCs that hire you to kill the person you are escorting. Think about bandits ambushing you, and offering to pay you to let them kill your VIP. And then think of the consequences when the relatives of that person find out what occurred.

all very good plot twists. i'm finding that the possible plot twists are almost endless. i don't think any of the 30-40-50? quest generators planner so far is based around a plot twist. they're all more of less straightforward quests so far. once the various possible types of straightforward quests are well covered, i may go back and make "twisted sister" versions of them. that way you never know if it a straight or twisted quest.  ; )
last night i finished up a first cut at both the sacred animals and the escort quest. both are straightforward, but they work.  using regular badguys did the trick for the sacred animals quest, although the herd is still just a random animal encounter that might kill both hunters and player alike. making the NPC a follower made the escort quest pretty trivial to code up.


One simple way to deal with applying consequences to escort quests is to simply have a registry / adventure's guild where you pick up the quest. If you're registered as the escort for someone, and that someone fails to arrive, well.. you fail the quest. Be careful of things like on death hooks, because often they don't make sense. For instance there have been times when playing Elder Scrolls games where I've killed someone and was witnessed by someone else, who I then killed, but yet you still get reported.


If you're going to have reporting mechanics, then you should spend the effort to make them work well with the rest of the gameplay. If I exterminate all of the witnesses before they can get to a guard, I should not have a bounty taken out on me, unless somehow my name is registered with regards to the people in question (i.e. I was hired for an escort)

#5308717 the dreaded "escort" quest

Posted by on 30 August 2016 - 01:09 PM

If an escort quest doesn't have a start point and an end point, then why is there a quest?


If you have a living world, then there's no reason why you could not simply encounter an NPC who is going from A to B at some point between A and B and get "hired" to escort them.

#5308548 the dreaded "escort" quest

Posted by on 29 August 2016 - 02:51 PM


I played Guild Wars 2 yesterday (for the first time in years) and one of the things I noticed about the escort quests there than I immediately liked was the NPC does not die completely. It can still go down but people could revive them just like they can revive other players. The only issue with that is the lack of failure so that would be more a design choice.

hmm....   un-fail-able quests aren't much of a challenge...


To be clear, many escort quests in Gw2 can be failed. For instance, if the NPC is not ressed within some timespan then the quest can fail.

If i implement the NPC as some sort of temporary follower, the player would gain all the follower interactions such as giving them medicinal hers, and staunching their wounds. along with all kinds of orders like wait, goto, follow, use missile/melee weapons, attack, target selection, use/don't use sneak mode, flee, maintain distance, etc.

Yes, and if you're escotring a trade caravan that has to remain on the roads, what then? Making the NPCs simply follow the player has always been one of those things that irritated me about some escort quests. Sometimes you just need to bite the bullet and realize that some escorts must run on a rail. Others can be a bit more freeform, but there still needs to be some sort of a gating concern to prevent the player from simply escorting the NPC to Timbuktu and back again, I.e. if I'm going from Divinity's Reach to Lion's arch, going via the Black Citadel is taking the long way round, and might not be the method most appreciated by the NPC. On the other hand, emergent gameplay can result when you allow arbitrary escort paths, such as assassin's on the way never being encountered, which can trigger other quest dialog (or future quest entries... such as lowing their guard because they weren't ambushed and thus thinking they're safer on the pot.)

#5297460 Single producer - multiple consumer fast queue?

Posted by on 21 June 2016 - 10:06 AM

First step: Write a lock based one, or better yet, use an existing queue such as ConcurrentQueue, which is already moderately lock free (source).
Second step: If profiling actually shows it to be a problem, then invest the time to replace it.


As for writing a lock free circular queue goes, for starters: Time consuming operations should be completed long before you ever attempt to insert the object into the queue. Your insertion into the queue should be one or more CAS operations based on the result of the CAS.

#5296499 How to avoid Singletons/global variables

Posted by on 14 June 2016 - 10:11 AM

4. Dependency Injection.
If you are familiar with SOLID development principles, you should know about handling dependencies.  In well-designed systems there should be interfaces for behavior.  Code should be written to accept objects that implement the interface rather than accept concrete types.  Then developers can build new concrete types and they will automatically integrate and work cleanly with the code.
If you have written your code according to SOLID principles, it is easy to inject the concrete class.  It sounds hard, but really it just means providing constructor parameter and/or a member function that accepts a new interface.  
For example, if you went with a combination of a texture loader / cache / proxy / pool rather than a monolithic "Manager" class, and each of the loader / cache / proxy / pool types had an interface, you could add a function that sets their owning pool, accepts an object that accepts the interface, and then the object uses the interface.  Alternatively, you can require the interface pointer be passed to any calls that need it, which is the most explicit way to do things but requires a bit of discipline.
When code needs several interfaces passed to it, it can also make sense to have a structure with a bunch of interface pointers. Fill out the structure with the active objects and pass the structure around for less typing.

As an additional note here, DIP can allow you to write unit tests against code that would otherwise be untestable. Since your concrete instances are merely taking interfaces, you can provide mock implementations of the interfaces and then back that with your test framework.

#5290154 Is it C# Territory?

Posted by on 04 May 2016 - 05:02 PM

Your good reason is "We have hundreds of thousands of man hours invested in our giant aging C++ code base, thus we'll be keeping that around. kthxbye."

#5260195 Return type of arbitrary function

Posted by on 02 November 2015 - 02:48 PM

#include <iostream>
#include <type_traits>

template<class C, class T, class... Args>
T result_of(T (C::*)(Args...)) {
    return T();

template<typename T>
class S {
    using ResultType = decltype(result_of(&T::C));

class A {
    int C(int) {
        return 0;

class B {
    float C(float, float) {
        return 0;

int main() {
    S<A>::ResultType x;

    S<B>::ResultType y;
    std::cout << typeid(y).name() << std::endl;

#5259304 Game development with assembly. Where to start?

Posted by on 27 October 2015 - 12:28 PM

...something fun like learn assembly. However displaying text on a console wasn't very exciting for me.

Writing assembly doesn't get much more exciting than that! It does get more tedious and much more difficult, however. You do graphics in the exact same way as you'd do it in C - just with more effort to manage the same data and make the same calls.

Pretty much. I mean... here's a simple triangle example that I wrote a while back...
.model flat, stdcall
option casemap :none

includelib <d3d11.lib>
includelib <d3dcompiler.lib>

@ArgRev MACRO arglist:REQ
    LOCAL txt, arg
    txt TEXTEQU <>
%   FOR arg, <arglist>
        txt CATSTR <arg>, <,>, txt

    txt SUBSTR  txt, 1, @SizeStr( %txt ) - 1
    txt CATSTR  <!<>, txt, <!>>
    EXITM txt

INVOKEC    MACRO comObject, methodNumber, args:VARARG
    LOCAL txt
    IFNB <args>
%       FOR arg, @ArgRev( <args> )
            push arg
    mov  ecx, dword ptr [comObject]
    push ecx
    mov  eax, [ecx]
    mov  edx, dword ptr [eax + methodNumber];
    call edx

RELEASE    MACRO comObject
     LOCAL skip
     cmp  comObject, 0
     jz  skip
     INVOKEC comObject, IUnknown_Release

DEFINEGUID          MACRO name, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11
name    DD _1
        DW _2
        DW _3
        DB _4
        DB _5
        DB _6
        DB _7
        DB _8
        DB _9
        DB _10
        DB _11

ExitProcess                     PROTO stdcall :DWORD
MessageBoxA                     PROTO stdcall :DWORD, :DWORD, :DWORD, :DWORD
RegisterClassExA                PROTO stdcall :DWORD
GetModuleHandleA                PROTO stdcall :DWORD
DefWindowProcA                  PROTO stdcall :DWORD, :DWORD, :DWORD, :DWORD
CreateWindowExA                 PROTO stdcall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
PostQuitMessage                 PROTO stdcall :DWORD
ShowWindow                      PROTO stdcall :DWORD, :DWORD
UpdateWindow                    PROTO stdcall :DWORD
PeekMessageA                    PROTO stdcall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
TranslateMessage                PROTO stdcall :DWORD
DispatchMessageA                PROTO stdcall :DWORD
D3DCompile                      PROTO stdcall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
D3DGetInputSignatureBlob        PROTO stdcall :DWORD, :DWORD, :DWORD

POINT                   STRUC 4
    x                      DWORD ?
    y                      DWORD ?
POINT                   ENDS

MSG                     STRUC 4
    hwnd                   DWORD ?
    message                DWORD ?
    wparam                 WORD  ?
    lparam                 DWORD ?
    time                   DWORD ?
    point                  POINT <>
MSG                     ENDS

WNDCLASSEX              STRUC 4
    cbSize                 DWORD SIZEOF(WNDCLASSEX)
    style                  DWORD CW_VREDRAW OR CW_HREDRAW OR CW_OWNDC
    lpfnWndProc            DWORD WndProc
    cbClsExtra             DWORD 0
    cbWndExtra             DWORD 0
    hInstance              DWORD ?
    hIcon                  DWORD 0
    hCursor                DWORD 0
    hbrBackground          DWORD COLOR_BACKGROUND
    lpszMenuName           DWORD 0
    lpszClassName          DWORD className
    hIconSm                DWORD 0
WNDCLASSEX              ENDS

    numerator              DWORD ?
    denominator            DWORD ?

    w                      DWORD 800
    h                      DWORD 600
    refreshRate            DXGI_RATIONAL <1, 60>
    format                 DWORD DXGI_FORMAT_R8G8B8A8_UNORM
    scanLineOrder          DWORD 0
    scaling                DWORD 0

    bufferDesc             DXGI_MODE_DESC <>
    sampleDesc             DXGI_RATIONAL <1, 0>
    usage                  DWORD 20h OR 40h
    bufferCount            DWORD 2
    window                 DWORD ?
    windowed               DWORD 1
    swapEffect             DWORD 0
    flags                  DWORD 0

    byteWidth               DWORD ?
    usage                   DWORD ?
    bindFlags               DWORD ?
    cpuAccessFlags          DWORD ?
    miscFlags               DWORD ?
    structByteStride        DWORD ?

    srcData                 DWORD ?
    scrap1                  DWORD 0
    scrap2                  DWORD 0

    semanticName            DWORD ?
    semanticIndex           DWORD ?
    format                  DWORD ?
    slot                    DWORD ?
    byteOffset              DWORD ?
    slotClass               DWORD ?
    dataStepRate            DWORD ?

D3D11_VIEWPORT          STRUC 4
    topLeftX                REAL4 0.0
    topLeftY                REAL4 0.0
    windowWidth             REAL4 800.0
    windowHeight            REAL4 600.0
    minDepth                REAL4 0.0
    maxDepth                REAL4 1.0
D3D11_VIEWPORT          ENDS

MB_OK                       EQU 0
SW_SHOW                     EQU 5
CW_VREDRAW                  EQU 1
CW_HREDRAW                  EQU 2
CW_OWNDC                    EQU 20h
WS_OVERLAPPED               EQU 00000000h
WS_MINIMIZEBOX              EQU 00020000h
WS_MAXIMIZEBOX              EQU 00020000h
WS_SYSMENU                  EQU 00080000h
WS_THICKFRAME               EQU 00040000h
WS_CAPTION                  EQU 00C00000h
WM_QUIT                     EQU 0012h

D3D_FEATURE_LEVEL_9_1               EQU 09100h
D3D_FEATURE_LEVEL_9_2               EQU 09200h
D3D_FEATURE_LEVEL_9_3               EQU 09300h
D3D_FEATURE_LEVEL_10_0              EQU 0a000h
D3D_FEATURE_LEVEL_10_1              EQU 0a100h
D3D_FEATURE_LEVEL_11_0              EQU 0b000h

IUnknown_QueryInterface     EQU 0h
IUnknown_AddRef             EQU 4h
IUnknown_Release            EQU 8h

ID3D10Blob_GetBufferData    EQU IUnknown_Release + 4
ID3D10Blob_GetBufferSize    EQU IUnknown_Release + 8

IDXGISwapChain_GetBuffer    EQU 24h
IDXGISwapChain_Present      EQU 20h

ID3D11Device_CreateRTView   EQU 24h
ID3D11Device_CreateVS       EQU 30h
ID3D11Device_CreatePS       EQU 3Ch
ID3D11Device_CreateBuffer   EQU 0Ch
ID3D11Device_CreateLayout   EQU 2Ch

ID3D11Context_ClearRTView   EQU 0C8h
ID3D11Context_OMSetRT       EQU 84h
ID3D11Context_IASetLayout   EQU 44h
ID3D11Context_VSSetShader   EQU 2Ch
ID3D11Context_PSSetShader   EQU 24h
ID3D11Context_IASetPrimTop  EQU 60h
ID3D11Context_RSSetViewport EQU 0B0h
ID3D11Context_IASetVertBuff EQU 48h
ID3D11Context_Draw          EQU 34h

msgTitle    DB "Oh shit son!", 0
regFail     DB "Failed to register window class.", 0
cwFail      DB "Failed to create window.", 0
showFail    DB "Failed to show window.", 0
updateFail  DB "Failed to update window.", 0
d3d11Fail1  DB "Failed to create D3D11 device.", 0
d3d11Fail2  DB "Failed to get back buffer from swap chain.", 0
d3d11Fail3  DB "Failed to create render target.", 0
d3d11Fail4  DB "Failed to compile pixel shader.", 0
d3d11Fail5  DB "Failed to compile vertex shader.", 0
d3d11Fail6  DB "Failed to get vertex shader layout.", 0
d3d11Fail7  DB "Failed to create vertex buffer.", 0
d3d11Fail8  DB "Failed to create input layout.", 0
d3d11Fail9  DB "Failed to create shader resource.", 0

messageIdx  DD regFail, cwFail, showFail, updateFail, d3d11Fail1, d3d11Fail2, d3d11Fail3, d3d11Fail4, d3d11Fail5, d3d11Fail6, d3d11Fail7, d3d11Fail8, d3d11Fail9

className   DB "TestClass", 0
windowTitle DB "My Window", 0
wndClass    WNDCLASSEX <>
swapChain   DD 0
device      DD 0
newFeatLvl  DD 0
context     DD 0

blackColor  DD 0, 0, 0, 0
backBuffer  DD 0
view        DD 0
DEFINEGUID  ID3D11Texture2D_GUID, 6f15aaf2h, 0d208h, 04e89h, 09ah, 0b4h, 048h, 095h, 035h, 0d3h, 04fh, 09Ch

viewport    D3D11_VIEWPORT <>

psSource    DB "struct VS_IN { float4 pos : POSITION; float4 col : COLOR; }; struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR; }; float4 PS( PS_IN input ) : SV_Target { return input.col; }", 0
psSourceLen DD $ - OFFSET psSource
psTarget    DB "ps_5_0", 0
psEntry     DB "PS", 0

vsSource    DB"struct VS_IN { float4 pos : POSITION; float4 col : COLOR; }; struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR; }; PS_IN VS( VS_IN input ) { PS_IN output = (PS_IN)0; output.pos = input.pos; output.col = input.col; return output; }", 0
vsSourceLen DD $ - OFFSET vsSource
vsTarget    DB "vs_5_0", 0
vsEntry     DB "VS", 0

vertData    REAL4 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 0.0, 1.0
            REAL4 0.5f, -0.5f, 0.5f, 1.0, 0.0, 1.0, 0.0, 1.0
            REAL4 -0.5f, -0.5f, 0.5f, 1.0, 0.0, 0.0, 1.0, 1.0

vertDesc    D3D11_BUFFER_DESC < 96, 0, 1, 0, 0, 0 >
vertSub     D3D11_SUBRESOURCE_DATA < vertData >
vertDescPos DB "POSITION", 0
vertDescCol DB "COLOR", 0
vertLayout  D3D11_INPUT_ELEMENT_DESC < OFFSET vertDescPos, 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, 0, 0 >
            D3D11_INPUT_ELEMENT_DESC < OFFSET vertDescCol, 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, 0, 0 >
vertStride  DD 32
vertOffset  DD 0

vertBuff    DD 0
inputLayout DD 0
psShader    DD 0
psBlob      DD 0
psBlobErr   DD 0
vsShader    DD 0
vsBlob      DD 0
vsBlobErr   DD 0
layoutBlob  DD 0
vsError     DD 0
blobPtr     DD 0
blobSize    DD 0

WndProc  PROC stdcall hwnd:DWORD, msg:DWORD, wparam:WORD, lparam:DWORD
    cmp    msg, 2
    jnz    done
    INVOKE PostQuitMessage, 0
    xor    eax, eax
    INVOKE DefWindowProcA, hwnd, msg, wparam, lparam
WndProc  ENDP

main  PROC
    LOCAL  hwnd:DWORD
    LOCAL  hmodule:DWORD
    LOCAL  msg:MSG

    INVOKE GetModuleHandleA, 0
    mov    hmodule, eax
    mov    wndClass.hInstance, eax

    INVOKE RegisterClassExA, OFFSET wndClass
    cmp    eax, 0
    mov    eax, 0
    jz     error

    INVOKE CreateWindowExA, 0, OFFSET className, OFFSET windowTitle, WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, 0, 0, hmodule, 0
    mov    hwnd, eax
    cmp    eax, 0
    mov    eax, 1
    jz     error

    INVOKE ShowWindow, hwnd, SW_SHOW
    INVOKE UpdateWindow, hwnd
    cmp    eax, 0
    mov    eax, 3
    jz     error

    mov    eax, hwnd
    mov    swapDesc.window, eax

    INVOKE D3D11CreateDeviceAndSwapChain, 0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, OFFSET featureLvl, 4, 7, OFFSET swapDesc, OFFSET swapChain, OFFSET device, OFFSET newFeatLvl, OFFSET context
    cmp    eax, 0
    mov    eax, 4
    jnz    error

    INVOKEC swapChain, IDXGISwapChain_GetBuffer, 0, OFFSET ID3D11Texture2D_GUID, OFFSET backBuffer
    cmp    eax, 0
    mov    eax, 5
    jnz    error

    INVOKEC device, ID3D11Device_CreateRTView, dword ptr [backBuffer], 0, OFFSET view
    cmp    eax, 0
    mov    eax, 6
    jnz    error

    INVOKE D3DCompile, OFFSET psSource, psSourceLen, 0, 0, 0, OFFSET psEntry, OFFSET psTarget, 0, 0, OFFSET psBlob, OFFSET psBlobErr
    cmp    eax, 0
    mov    eax, 7
    jnz    error

    INVOKE D3DCompile, OFFSET vsSource, vsSourceLen, 0, 0, 0, OFFSET vsEntry, OFFSET vsTarget, 0, 0, OFFSET vsBlob, OFFSET vsBlobErr
    cmp    eax, 0
    mov    eax, 8
    jnz    error

    INVOKEC vsBlob, ID3D10Blob_GetBufferData
    mov    blobPtr, eax

    INVOKEC vsBlob, ID3D10Blob_GetBufferSize
    mov    blobSize, eax

    INVOKE D3DGetInputSignatureBlob, blobPtr, blobSize, OFFSET layoutBlob
    cmp    eax, 0
    mov    eax, 9
    jnz    error

    INVOKEC device, ID3D11Device_CreateBuffer, OFFSET vertDesc, OFFSET vertSub, OFFSET vertBuff
    cmp    eax, 0
    mov    eax, 10
    jnz    error

    INVOKEC layoutBlob, ID3D10Blob_GetBufferSize
    mov    blobSize, eax

    INVOKEC layoutBlob, ID3D10Blob_GetBufferData

    INVOKEC device, ID3D11Device_CreateLayout, OFFSET vertLayout, 2, eax, blobSize, OFFSET inputLayout
    cmp    eax, 0
    mov    eax, 11
    jnz    error

    INVOKEC vsBlob, ID3D10Blob_GetBufferData
    mov    blobPtr, eax

    INVOKEC vsBlob, ID3D10Blob_GetBufferSize

    INVOKEC device, ID3D11Device_CreateVS, blobPtr, eax, 0, OFFSET vsShader
    cmp    eax, 0
    mov    eax, 12
    jnz    error

    INVOKEC psBlob, ID3D10Blob_GetBufferData
    mov    blobPtr, eax

    INVOKEC psBlob, ID3D10Blob_GetBufferSize

    INVOKEC device, ID3D11Device_CreatePS, blobPtr, eax, 0, OFFSET psShader
    cmp    eax, 0
    mov    eax, 12
    jnz    error

    RELEASE psBlob
    RELEASE vsBlob
    RELEASE layoutBlob

    INVOKEC context, ID3D11Context_OMSetRT, 1, OFFSET view, 0
    INVOKEC context, ID3D11Context_IASetLayout, inputLayout
    INVOKEC context, ID3D11Context_VSSetShader, vsShader, 0, 0
    INVOKEC context, ID3D11Context_PSSetShader, psShader, 0, 0
    INVOKEC context, ID3D11Context_RSSetViewport, 1, OFFSET viewport
    INVOKEC context, ID3D11Context_IASetVertBuff, 0, 1, OFFSET vertBuff, OFFSET vertStride, OFFSET vertOffset
    INVOKE PeekMessageA, ADDR msg, 0, 0, 0, 1
    cmp    eax, 0
    jz     gameNext
    cmp    msg.message, WM_QUIT
    jz     done
    INVOKE TranslateMessage, ADDR msg
    INVOKE DispatchMessageA, ADDR msg
    jmp    msgLoop
    INVOKEC context, ID3D11Context_ClearRTView, view, OFFSET blackColor
    INVOKEC context, ID3D11Context_Draw, 3, 0
    INVOKEC swapChain, IDXGISwapChain_Present, 0, 0
    jmp    gameLoop

    RELEASE view
    RELEASE backBuffer
    RELEASE swapChain
    RELEASE device
    RELEASE context
    RELEASE vsShader
    RELEASE psShader
    RELEASE inputLayout
    RELEASE vertBuff
    INVOKE ExitProcess, eax
    mov    eax, messageIdx[eax*4]
    INVOKE MessageBoxA, 0, eax, ADDR msgTitle, MB_OK
    jmp done
main  ENDP
END main

#5257959 Does calling ~myclass() (destructor) deletes the object?

Posted by on 19 October 2015 - 01:50 PM

	if (pdata != NULL) delete [] pdata;

If you do that, do this:
if (pdata != NULL)
    delete[] pdata;
    pdata = NULL;
In other words, make sure that your object is in a valid state in case someone calls kill twice, or kill once and delete once.

if you do that... do this:
    delete[] pdata;
    pdata = NULL;
Hooray! A useless null check is gone.

#5257957 Does calling ~myclass() (destructor) deletes the object?

Posted by on 19 October 2015 - 01:45 PM

I had a strange problem i was appending an array using delete/new
but after creation of new array i had to put the structs in it (texture loading- whenever i loaded texture that wasnt 256x256 i had to resize it -> ther i called mytexture[i].~TGLTexture(); //it seems that was the problem i had to write another function that wasnt named ~TGLTexture() with the exact code.
So my question is: does calling a destructor w/o delete, deletes the object? it seems that yes but i didint find anythig on the net about it

No. Construction and destruction are two entirely separate things in C++.

You should never call the destructor directly. Always use delete.

There are plenty of reasons to call destructors directly. Placement newed objects for instance. In collections, etc.

#5254901 Why did COD: AW move every file into the same folder where .exe is?

Posted by on 30 September 2015 - 06:24 PM

I do have an issue with directories sometimes, it's "\\" or "\" or "/"  ......  agghhh

Just FYI, Windows has allowed forward slashes "/" as directory delimiters for a long time.

Since DOS 1.0.

As for paths in games... Why would you ever take a path from a designer and not normalize it. If it's a programmer doing it, then you should have better path creation tools and/or normalize them.

Frankly, if you're hard coding paths into your runtime... You're going to have other issues than just platform porting.

#5254878 How can I make a text parser?

Posted by on 30 September 2015 - 03:09 PM

Recursive descent parsers are pretty easy to implement.
Generally if you can make a game you shouldn't have a problem understanding simple RD parsers.
Personally for anything more advanced than a key value pair format, I'd be tempted to use YACC and BISON and friends and not reinvent the whole car never mind it's wheel...

Personally... If I'm going to be using something more advanced than is necessary to parse json/xml using an off the shelf parser...
It suggests you should probably plug in a proper scripting solution (lua, pythong, etc), instead of designing your own language. Stick to standard formats (like JSON) for data. It'll save you a ton of useless wasted effort.

#5253476 Best language for solving diamond problem & is this a good idea for multi...

Posted by on 22 September 2015 - 11:06 AM

I suspect most people here will suggest trying composition instead of using inheritance at all. It's easier to get what you want, and you don't have to fight with the language.


Most cases where people encounter the diamond problem, in my experience, are cases where composition was more likely to be the appropriate choice.

#5252728 Why std::copy is faster than std::memcpy ?

Posted by on 17 September 2015 - 01:15 PM

Nice to know, but since the compiler optimize for memcpy, it's safer to always use memcpy, true ?
About the timer, good point, I should stop to use SDL timer and implement a custom one with better precision.

If you are in C++, you should use std::copy. memcpy is dangerous, it doesn't invoke copy or move constructors, and completely ignores type safety.

#5251800 Why std::copy is faster than std::memcpy ?

Posted by on 11 September 2015 - 06:43 PM

First things first: That's not how most std::copy implementations work.


If you actually look at it you will see a lot of them use compile time type deduction to optimize the amount of work they need to do. Furthermore, as they're templates and fairly small, they have a high chance of being inlined. Lastly, due to the fact that the compiler has exact information about the size of the objects it can explicitly optimize the copy for your type. Lastly, a lot of times, if copy can deduce the point is a pointer, then it can simply delegate to memmove.


memcpy tends to be located in the msvcrt dll, and as such will typically not be inlined (LTCG can do this though). It also is quite a bit more complex as it does not actually know what you're going to be passing into it at compile time, and thus has to do more work to efficiently move things around.


All of that being said, in general the two should perform roughly the same.